mirror of
https://github.com/vale981/ray
synced 2025-03-06 10:31:39 -05:00
[Dashboard] Update dependencies and add linting rules (#7779)
This commit is contained in:
parent
0cfb6488a7
commit
090a8474b0
36 changed files with 6296 additions and 3109 deletions
8533
python/ray/dashboard/client/package-lock.json
generated
8533
python/ray/dashboard/client/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -3,27 +3,29 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material-ui/core": "^4.3.3",
|
"@material-ui/core": "^4.9.7",
|
||||||
"@material-ui/icons": "^4.2.1",
|
"@material-ui/icons": "^4.9.1",
|
||||||
"@reduxjs/toolkit": "^1.0.4",
|
"@reduxjs/toolkit": "^1.3.1",
|
||||||
"@types/classnames": "^2.2.9",
|
"@types/classnames": "^2.2.10",
|
||||||
"@types/jest": "24.0.18",
|
"@types/jest": "25.1.4",
|
||||||
"@types/node": "12.7.2",
|
"@types/node": "13.9.5",
|
||||||
"@types/react": "16.9.2",
|
"@types/react": "16.9.26",
|
||||||
"@types/react-dom": "16.9.0",
|
"@types/react-dom": "16.9.5",
|
||||||
"@types/react-redux": "^7.1.5",
|
"@types/react-redux": "^7.1.7",
|
||||||
"@types/react-router-dom": "^4.3.5",
|
"@types/react-router-dom": "^5.1.3",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"react": "^16.9.0",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.9.0",
|
"react-dom": "^16.13.1",
|
||||||
"react-redux": "^7.1.3",
|
"react-redux": "^7.2.0",
|
||||||
"react-router-dom": "^5.0.1",
|
"react-router-dom": "^5.1.2",
|
||||||
"react-scripts": "3.1.2",
|
"react-scripts": "3.4.1",
|
||||||
"typeface-roboto": "0.0.75",
|
"typeface-roboto": "0.0.75",
|
||||||
"typescript": "3.5.3"
|
"typescript": "3.8.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^1.18.2"
|
"eslint-plugin-import": "^2.20.1",
|
||||||
|
"eslint-plugin-prefer-arrow": "^1.1.7",
|
||||||
|
"prettier": "^2.0.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
@ -32,7 +34,64 @@
|
||||||
"eject": "react-scripts eject"
|
"eject": "react-scripts eject"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "react-app"
|
"extends": [
|
||||||
|
"plugin:import/warnings",
|
||||||
|
"react-app"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"prefer-arrow"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"@typescript-eslint/consistent-type-definitions": [
|
||||||
|
"error",
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"comma-dangle": [
|
||||||
|
"warn",
|
||||||
|
"always-multiline"
|
||||||
|
],
|
||||||
|
"curly": [
|
||||||
|
"warn",
|
||||||
|
"all"
|
||||||
|
],
|
||||||
|
"eqeqeq": [
|
||||||
|
"error",
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"import/order": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"alphabetize": {
|
||||||
|
"order": "asc",
|
||||||
|
"caseInsensitive": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-var": "error",
|
||||||
|
"prefer-arrow/prefer-arrow-functions": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"disallowPrototype": true,
|
||||||
|
"singleReturnOnly": false,
|
||||||
|
"classPropertiesAllowed": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prefer-const": "error",
|
||||||
|
"react/jsx-fragments": [
|
||||||
|
"warn",
|
||||||
|
"element"
|
||||||
|
],
|
||||||
|
"sort-imports": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"ignoreCase": true,
|
||||||
|
"ignoreDeclarationSort": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"prettier": {
|
||||||
|
"trailingComma": "all"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import CssBaseline from "@material-ui/core/CssBaseline";
|
import { CssBaseline } from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Provider } from "react-redux";
|
import { Provider } from "react-redux";
|
||||||
import { BrowserRouter, Route } from "react-router-dom";
|
import { BrowserRouter, Route } from "react-router-dom";
|
||||||
|
|
|
@ -22,7 +22,7 @@ const get = async <T>(path: string, params: { [key: string]: any }) => {
|
||||||
return result as T;
|
return result as T;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface RayConfigResponse {
|
export type RayConfigResponse = {
|
||||||
min_workers: number;
|
min_workers: number;
|
||||||
max_workers: number;
|
max_workers: number;
|
||||||
initial_workers: number;
|
initial_workers: number;
|
||||||
|
@ -30,11 +30,11 @@ export interface RayConfigResponse {
|
||||||
idle_timeout_minutes: number;
|
idle_timeout_minutes: number;
|
||||||
head_type: string;
|
head_type: string;
|
||||||
worker_type: string;
|
worker_type: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getRayConfig = () => get<RayConfigResponse>("/api/ray_config", {});
|
export const getRayConfig = () => get<RayConfigResponse>("/api/ray_config", {});
|
||||||
|
|
||||||
export interface NodeInfoResponse {
|
export type NodeInfoResponse = {
|
||||||
clients: Array<{
|
clients: Array<{
|
||||||
now: number;
|
now: number;
|
||||||
hostname: string;
|
hostname: string;
|
||||||
|
@ -82,11 +82,11 @@ export interface NodeInfoResponse {
|
||||||
[pid: string]: number;
|
[pid: string]: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getNodeInfo = () => get<NodeInfoResponse>("/api/node_info", {});
|
export const getNodeInfo = () => get<NodeInfoResponse>("/api/node_info", {});
|
||||||
|
|
||||||
export interface RayletInfoResponse {
|
export type RayletInfoResponse = {
|
||||||
nodes: {
|
nodes: {
|
||||||
[ip: string]: {
|
[ip: string]: {
|
||||||
extraInfo?: string;
|
extraInfo?: string;
|
||||||
|
@ -130,33 +130,33 @@ export interface RayletInfoResponse {
|
||||||
invalidStateType?: "infeasibleActor" | "pendingActor";
|
invalidStateType?: "infeasibleActor" | "pendingActor";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getRayletInfo = () =>
|
export const getRayletInfo = () =>
|
||||||
get<RayletInfoResponse>("/api/raylet_info", {});
|
get<RayletInfoResponse>("/api/raylet_info", {});
|
||||||
|
|
||||||
export interface ErrorsResponse {
|
export type ErrorsResponse = {
|
||||||
[pid: string]: Array<{
|
[pid: string]: Array<{
|
||||||
message: string;
|
message: string;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
type: string;
|
type: string;
|
||||||
}>;
|
}>;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getErrors = (hostname: string, pid: number | null) =>
|
export const getErrors = (hostname: string, pid: number | null) =>
|
||||||
get<ErrorsResponse>("/api/errors", {
|
get<ErrorsResponse>("/api/errors", {
|
||||||
hostname,
|
hostname,
|
||||||
pid: pid === null ? "" : pid
|
pid: pid === null ? "" : pid,
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface LogsResponse {
|
export type LogsResponse = {
|
||||||
[pid: string]: string[];
|
[pid: string]: string[];
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getLogs = (hostname: string, pid: number | null) =>
|
export const getLogs = (hostname: string, pid: number | null) =>
|
||||||
get<LogsResponse>("/api/logs", {
|
get<LogsResponse>("/api/logs", {
|
||||||
hostname,
|
hostname,
|
||||||
pid: pid === null ? "" : pid
|
pid: pid === null ? "" : pid,
|
||||||
});
|
});
|
||||||
|
|
||||||
export type LaunchProfilingResponse = string;
|
export type LaunchProfilingResponse = string;
|
||||||
|
@ -164,12 +164,12 @@ export type LaunchProfilingResponse = string;
|
||||||
export const launchProfiling = (
|
export const launchProfiling = (
|
||||||
nodeId: string,
|
nodeId: string,
|
||||||
pid: number,
|
pid: number,
|
||||||
duration: number
|
duration: number,
|
||||||
) =>
|
) =>
|
||||||
get<LaunchProfilingResponse>("/api/launch_profiling", {
|
get<LaunchProfilingResponse>("/api/launch_profiling", {
|
||||||
node_id: nodeId,
|
node_id: nodeId,
|
||||||
pid: pid,
|
pid: pid,
|
||||||
duration: duration
|
duration: duration,
|
||||||
});
|
});
|
||||||
|
|
||||||
export type CheckProfilingStatusResponse =
|
export type CheckProfilingStatusResponse =
|
||||||
|
@ -179,26 +179,26 @@ export type CheckProfilingStatusResponse =
|
||||||
|
|
||||||
export const checkProfilingStatus = (profilingId: string) =>
|
export const checkProfilingStatus = (profilingId: string) =>
|
||||||
get<CheckProfilingStatusResponse>("/api/check_profiling_status", {
|
get<CheckProfilingStatusResponse>("/api/check_profiling_status", {
|
||||||
profiling_id: profilingId
|
profiling_id: profilingId,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getProfilingResultURL = (profilingId: string) =>
|
export const getProfilingResultURL = (profilingId: string) =>
|
||||||
`${base}/speedscope/index.html#profileURL=${encodeURIComponent(
|
`${base}/speedscope/index.html#profileURL=${encodeURIComponent(
|
||||||
`${base}/api/get_profiling_info?profiling_id=${profilingId}`
|
`${base}/api/get_profiling_info?profiling_id=${profilingId}`,
|
||||||
)}`;
|
)}`;
|
||||||
|
|
||||||
export const launchKillActor = (
|
export const launchKillActor = (
|
||||||
actorId: string,
|
actorId: string,
|
||||||
actorIpAddress: string,
|
actorIpAddress: string,
|
||||||
actorPort: number
|
actorPort: number,
|
||||||
) =>
|
) =>
|
||||||
get<string>("/api/kill_actor", {
|
get<string>("/api/kill_actor", {
|
||||||
actor_id: actorId,
|
actor_id: actorId,
|
||||||
ip_address: actorIpAddress,
|
ip_address: actorIpAddress,
|
||||||
port: actorPort
|
port: actorPort,
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface TuneTrial {
|
export type TuneTrial = {
|
||||||
date: string;
|
date: string;
|
||||||
episodes_total: string;
|
episodes_total: string;
|
||||||
experiment_id: string;
|
experiment_id: string;
|
||||||
|
@ -221,17 +221,17 @@ export interface TuneTrial {
|
||||||
job_id: string;
|
job_id: string;
|
||||||
params: { [key: string]: string | number };
|
params: { [key: string]: string | number };
|
||||||
metrics: { [key: string]: string | number };
|
metrics: { [key: string]: string | number };
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface TuneJobResponse {
|
export type TuneJobResponse = {
|
||||||
trial_records: { [key: string]: TuneTrial };
|
trial_records: { [key: string]: TuneTrial };
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getTuneInfo = () => get<TuneJobResponse>("/api/tune_info", {});
|
export const getTuneInfo = () => get<TuneJobResponse>("/api/tune_info", {});
|
||||||
|
|
||||||
export interface TuneAvailabilityResponse {
|
export type TuneAvailabilityResponse = {
|
||||||
available: boolean;
|
available: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const getTuneAvailability = () =>
|
export const getTuneAvailability = () =>
|
||||||
get<TuneAvailabilityResponse>("/api/tune_availability", {});
|
get<TuneAvailabilityResponse>("/api/tune_availability", {});
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
import Dialog from "@material-ui/core/Dialog";
|
import {
|
||||||
import IconButton from "@material-ui/core/IconButton";
|
createStyles,
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
Dialog,
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
IconButton,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
Theme,
|
||||||
import Typography from "@material-ui/core/Typography";
|
Typography,
|
||||||
|
WithStyles,
|
||||||
|
withStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import CloseIcon from "@material-ui/icons/Close";
|
import CloseIcon from "@material-ui/icons/Close";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
paper: {
|
paper: {
|
||||||
padding: theme.spacing(3)
|
padding: theme.spacing(3),
|
||||||
},
|
},
|
||||||
closeButton: {
|
closeButton: {
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
right: theme.spacing(1.5),
|
right: theme.spacing(1.5),
|
||||||
top: theme.spacing(1.5),
|
top: theme.spacing(1.5),
|
||||||
zIndex: 1
|
zIndex: 1,
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
borderBottomColor: theme.palette.divider,
|
borderBottomColor: theme.palette.divider,
|
||||||
|
@ -25,14 +28,14 @@ const styles = (theme: Theme) =>
|
||||||
fontSize: "1.5rem",
|
fontSize: "1.5rem",
|
||||||
lineHeight: 1,
|
lineHeight: 1,
|
||||||
marginBottom: theme.spacing(3),
|
marginBottom: theme.spacing(3),
|
||||||
paddingBottom: theme.spacing(3)
|
paddingBottom: theme.spacing(3),
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
handleClose: () => void;
|
handleClose: () => void;
|
||||||
title: string;
|
title: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
class DialogWithTitle extends React.Component<
|
class DialogWithTitle extends React.Component<
|
||||||
Props & WithStyles<typeof styles>
|
Props & WithStyles<typeof styles>
|
||||||
|
|
|
@ -1,25 +1,28 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import {
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
createStyles,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
Table,
|
||||||
import Table from "@material-ui/core/Table";
|
TableBody,
|
||||||
import TableBody from "@material-ui/core/TableBody";
|
TableCell,
|
||||||
import TableCell from "@material-ui/core/TableCell";
|
TableRow,
|
||||||
import TableRow from "@material-ui/core/TableRow";
|
Theme,
|
||||||
|
withStyles,
|
||||||
|
WithStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
root: {
|
root: {
|
||||||
overflowX: "auto"
|
overflowX: "auto",
|
||||||
},
|
},
|
||||||
cell: {
|
cell: {
|
||||||
borderWidth: 0,
|
borderWidth: 0,
|
||||||
fontFamily: "SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace",
|
fontFamily: "SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace",
|
||||||
padding: 0,
|
padding: 0,
|
||||||
"&:last-child": {
|
"&:last-child": {
|
||||||
paddingRight: 0
|
paddingRight: 0,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
lineNumber: {
|
lineNumber: {
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
|
@ -30,18 +33,18 @@ const styles = (theme: Theme) =>
|
||||||
// Use a ::before pseudo-element for the line number so that it won't
|
// Use a ::before pseudo-element for the line number so that it won't
|
||||||
// interact with user selections or searching.
|
// interact with user selections or searching.
|
||||||
"&::before": {
|
"&::before": {
|
||||||
content: "attr(data-line-number)"
|
content: "attr(data-line-number)",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
line: {
|
line: {
|
||||||
textAlign: "left",
|
textAlign: "left",
|
||||||
whiteSpace: "pre-wrap"
|
whiteSpace: "pre-wrap",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
lines: string[];
|
lines: string[];
|
||||||
}
|
};
|
||||||
|
|
||||||
class NumberedLines extends React.Component<Props & WithStyles<typeof styles>> {
|
class NumberedLines extends React.Component<Props & WithStyles<typeof styles>> {
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import { createStyles, Theme, withStyles, WithStyles } from "@material-ui/core";
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
|
||||||
import React, { HTMLAttributes } from "react";
|
import React, { HTMLAttributes } from "react";
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
|
@ -9,9 +7,9 @@ const styles = (theme: Theme) =>
|
||||||
color: theme.palette.primary.main,
|
color: theme.palette.primary.main,
|
||||||
"&:hover": {
|
"&:hover": {
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
textDecoration: "underline"
|
textDecoration: "underline",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
class SpanButton extends React.Component<
|
class SpanButton extends React.Component<
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import { createStyles, Theme, withStyles, WithStyles } from "@material-ui/core";
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const blend = (
|
const blend = (
|
||||||
[r1, g1, b1]: number[],
|
[r1, g1, b1]: number[],
|
||||||
[r2, g2, b2]: number[],
|
[r2, g2, b2]: number[],
|
||||||
ratio: number
|
ratio: number,
|
||||||
) => [
|
) => [
|
||||||
r1 * (1 - ratio) + r2 * ratio,
|
r1 * (1 - ratio) + r2 * ratio,
|
||||||
g1 * (1 - ratio) + g2 * ratio,
|
g1 * (1 - ratio) + g2 * ratio,
|
||||||
b1 * (1 - ratio) + b2 * ratio
|
b1 * (1 - ratio) + b2 * ratio,
|
||||||
];
|
];
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
|
@ -18,18 +16,18 @@ const styles = (theme: Theme) =>
|
||||||
root: {
|
root: {
|
||||||
borderColor: theme.palette.divider,
|
borderColor: theme.palette.divider,
|
||||||
borderStyle: "solid",
|
borderStyle: "solid",
|
||||||
borderWidth: 1
|
borderWidth: 1,
|
||||||
},
|
},
|
||||||
inner: {
|
inner: {
|
||||||
paddingLeft: theme.spacing(1),
|
paddingLeft: theme.spacing(1),
|
||||||
paddingRight: theme.spacing(1)
|
paddingRight: theme.spacing(1),
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
percent: number;
|
percent: number;
|
||||||
text: string;
|
text: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
class UsageBar extends React.Component<Props & WithStyles<typeof styles>> {
|
class UsageBar extends React.Component<Props & WithStyles<typeof styles>> {
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
export const formatByteAmount = (
|
export const formatByteAmount = (
|
||||||
amount: number,
|
amount: number,
|
||||||
unit: "mebibyte" | "gibibyte"
|
unit: "mebibyte" | "gibibyte",
|
||||||
) =>
|
) =>
|
||||||
`${(
|
`${(
|
||||||
amount / (unit === "mebibyte" ? Math.pow(1024, 2) : Math.pow(1024, 3))
|
amount / (unit === "mebibyte" ? Math.pow(1024, 2) : Math.pow(1024, 3))
|
||||||
|
@ -9,7 +9,7 @@ export const formatByteAmount = (
|
||||||
export const formatUsage = (
|
export const formatUsage = (
|
||||||
used: number,
|
used: number,
|
||||||
total: number,
|
total: number,
|
||||||
unit: "mebibyte" | "gibibyte"
|
unit: "mebibyte" | "gibibyte",
|
||||||
) => {
|
) => {
|
||||||
const usedFormatted = formatByteAmount(used, unit);
|
const usedFormatted = formatByteAmount(used, unit);
|
||||||
const totalFormatted = formatByteAmount(total, unit);
|
const totalFormatted = formatByteAmount(total, unit);
|
||||||
|
@ -27,6 +27,6 @@ export const formatDuration = (durationInSeconds: number) => {
|
||||||
durationDays ? `${durationDays}d` : "",
|
durationDays ? `${durationDays}d` : "",
|
||||||
`${pad(durationHours)}h`,
|
`${pad(durationHours)}h`,
|
||||||
`${pad(durationMinutes)}m`,
|
`${pad(durationMinutes)}m`,
|
||||||
`${pad(durationSeconds)}s`
|
`${pad(durationSeconds)}s`,
|
||||||
].join(" ");
|
].join(" ");
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import {
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
createStyles,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
Tab,
|
||||||
import Tab from "@material-ui/core/Tab";
|
Tabs,
|
||||||
import Tabs from "@material-ui/core/Tabs";
|
Theme,
|
||||||
import Typography from "@material-ui/core/Typography";
|
Typography,
|
||||||
|
WithStyles,
|
||||||
|
withStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { getNodeInfo, getRayletInfo, getTuneAvailability } from "../../api";
|
import { getNodeInfo, getRayletInfo, getTuneAvailability } from "../../api";
|
||||||
|
@ -21,19 +24,19 @@ const styles = (theme: Theme) =>
|
||||||
backgroundColor: theme.palette.background.paper,
|
backgroundColor: theme.palette.background.paper,
|
||||||
padding: theme.spacing(2),
|
padding: theme.spacing(2),
|
||||||
"& > :not(:first-child)": {
|
"& > :not(:first-child)": {
|
||||||
marginTop: theme.spacing(4)
|
marginTop: theme.spacing(4),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
tabs: {
|
tabs: {
|
||||||
borderBottomColor: theme.palette.divider,
|
borderBottomColor: theme.palette.divider,
|
||||||
borderBottomStyle: "solid",
|
borderBottomStyle: "solid",
|
||||||
borderBottomWidth: 1
|
borderBottomWidth: 1,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = (state: StoreState) => ({
|
const mapStateToProps = (state: StoreState) => ({
|
||||||
tab: state.dashboard.tab,
|
tab: state.dashboard.tab,
|
||||||
tuneAvailability: state.dashboard.tuneAvailability
|
tuneAvailability: state.dashboard.tuneAvailability,
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = dashboardActions;
|
const mapDispatchToProps = dashboardActions;
|
||||||
|
@ -50,7 +53,7 @@ class Dashboard extends React.Component<
|
||||||
const [nodeInfo, rayletInfo, tuneAvailability] = await Promise.all([
|
const [nodeInfo, rayletInfo, tuneAvailability] = await Promise.all([
|
||||||
getNodeInfo(),
|
getNodeInfo(),
|
||||||
getRayletInfo(),
|
getRayletInfo(),
|
||||||
getTuneAvailability()
|
getTuneAvailability(),
|
||||||
]);
|
]);
|
||||||
this.props.setNodeAndRayletInfo({ nodeInfo, rayletInfo });
|
this.props.setNodeAndRayletInfo({ nodeInfo, rayletInfo });
|
||||||
this.props.setTuneAvailability({ tuneAvailability });
|
this.props.setTuneAvailability({ tuneAvailability });
|
||||||
|
@ -80,7 +83,7 @@ class Dashboard extends React.Component<
|
||||||
{ label: "Machine view", component: NodeInfo },
|
{ label: "Machine view", component: NodeInfo },
|
||||||
{ label: "Logical view", component: LogicalView },
|
{ label: "Logical view", component: LogicalView },
|
||||||
{ label: "Ray config", component: RayConfig },
|
{ label: "Ray config", component: RayConfig },
|
||||||
{ label: "Tune", component: Tune }
|
{ label: "Tune", component: Tune },
|
||||||
];
|
];
|
||||||
|
|
||||||
// if Tune information is not available, remove Tune tab from the dashboard
|
// if Tune information is not available, remove Tune tab from the dashboard
|
||||||
|
@ -112,5 +115,5 @@ class Dashboard extends React.Component<
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
mapDispatchToProps
|
mapDispatchToProps,
|
||||||
)(withStyles(styles)(Dashboard));
|
)(withStyles(styles)(Dashboard));
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import {
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
createStyles,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
Theme,
|
||||||
import Typography from "@material-ui/core/Typography";
|
Typography,
|
||||||
|
WithStyles,
|
||||||
|
withStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { StoreState } from "../../store";
|
import { StoreState } from "../../store";
|
||||||
|
@ -9,23 +12,23 @@ import { StoreState } from "../../store";
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
root: {
|
root: {
|
||||||
marginTop: theme.spacing(2)
|
marginTop: theme.spacing(2),
|
||||||
},
|
},
|
||||||
lastUpdated: {
|
lastUpdated: {
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
fontSize: "0.8125rem",
|
fontSize: "0.8125rem",
|
||||||
textAlign: "center"
|
textAlign: "center",
|
||||||
},
|
},
|
||||||
error: {
|
error: {
|
||||||
color: theme.palette.error.main,
|
color: theme.palette.error.main,
|
||||||
fontSize: "0.8125rem",
|
fontSize: "0.8125rem",
|
||||||
textAlign: "center"
|
textAlign: "center",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = (state: StoreState) => ({
|
const mapStateToProps = (state: StoreState) => ({
|
||||||
lastUpdatedAt: state.dashboard.lastUpdatedAt,
|
lastUpdatedAt: state.dashboard.lastUpdatedAt,
|
||||||
error: state.dashboard.error
|
error: state.dashboard.error,
|
||||||
});
|
});
|
||||||
|
|
||||||
class LastUpdated extends React.Component<
|
class LastUpdated extends React.Component<
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import Collapse from "@material-ui/core/Collapse";
|
import {
|
||||||
import orange from "@material-ui/core/colors/orange";
|
Collapse,
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
createStyles,
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
Theme,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
Typography,
|
||||||
import Typography from "@material-ui/core/Typography";
|
withStyles,
|
||||||
|
WithStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
checkProfilingStatus,
|
checkProfilingStatus,
|
||||||
|
@ -11,7 +13,7 @@ import {
|
||||||
getProfilingResultURL,
|
getProfilingResultURL,
|
||||||
launchKillActor,
|
launchKillActor,
|
||||||
launchProfiling,
|
launchProfiling,
|
||||||
RayletInfoResponse
|
RayletInfoResponse,
|
||||||
} from "../../../api";
|
} from "../../../api";
|
||||||
import Actors from "./Actors";
|
import Actors from "./Actors";
|
||||||
|
|
||||||
|
@ -22,47 +24,47 @@ const styles = (theme: Theme) =>
|
||||||
borderStyle: "solid",
|
borderStyle: "solid",
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
marginTop: theme.spacing(2),
|
marginTop: theme.spacing(2),
|
||||||
padding: theme.spacing(2)
|
padding: theme.spacing(2),
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
fontSize: "0.75rem"
|
fontSize: "0.75rem",
|
||||||
},
|
},
|
||||||
action: {
|
action: {
|
||||||
color: theme.palette.primary.main,
|
color: theme.palette.primary.main,
|
||||||
textDecoration: "none",
|
textDecoration: "none",
|
||||||
"&:hover": {
|
"&:hover": {
|
||||||
cursor: "pointer"
|
cursor: "pointer",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
invalidStateTypeInfeasible: {
|
invalidStateTypeInfeasible: {
|
||||||
color: theme.palette.error.main
|
color: theme.palette.error.main,
|
||||||
},
|
},
|
||||||
invalidStateTypePendingActor: {
|
invalidStateTypePendingActor: {
|
||||||
color: orange[500]
|
color: theme.palette.secondary.main,
|
||||||
},
|
},
|
||||||
information: {
|
information: {
|
||||||
fontSize: "0.875rem"
|
fontSize: "0.875rem",
|
||||||
},
|
},
|
||||||
datum: {
|
datum: {
|
||||||
"&:not(:first-child)": {
|
"&:not(:first-child)": {
|
||||||
marginLeft: theme.spacing(2)
|
marginLeft: theme.spacing(2),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
webuiDisplay: {
|
webuiDisplay: {
|
||||||
fontSize: "0.875rem"
|
fontSize: "0.875rem",
|
||||||
},
|
},
|
||||||
inlineHTML: {
|
inlineHTML: {
|
||||||
fontSize: "0.875rem",
|
fontSize: "0.875rem",
|
||||||
display: "inline"
|
display: "inline",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
actor: RayletInfoResponse["actors"][keyof RayletInfoResponse["actors"]];
|
actor: RayletInfoResponse["actors"][keyof RayletInfoResponse["actors"]];
|
||||||
}
|
};
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
expanded: boolean;
|
expanded: boolean;
|
||||||
profiling: {
|
profiling: {
|
||||||
[profilingId: string]: {
|
[profilingId: string]: {
|
||||||
|
@ -70,12 +72,12 @@ interface State {
|
||||||
latestResponse: CheckProfilingStatusResponse | null;
|
latestResponse: CheckProfilingStatusResponse | null;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
|
class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
|
||||||
state: State = {
|
state: State = {
|
||||||
expanded: true,
|
expanded: true,
|
||||||
profiling: {}
|
profiling: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
setExpanded = (expanded: boolean) => () => {
|
setExpanded = (expanded: boolean) => () => {
|
||||||
|
@ -88,24 +90,24 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
|
||||||
const profilingId = await launchProfiling(
|
const profilingId = await launchProfiling(
|
||||||
actor.nodeId,
|
actor.nodeId,
|
||||||
actor.pid,
|
actor.pid,
|
||||||
duration
|
duration,
|
||||||
);
|
);
|
||||||
this.setState(state => ({
|
this.setState((state) => ({
|
||||||
profiling: {
|
profiling: {
|
||||||
...state.profiling,
|
...state.profiling,
|
||||||
[profilingId]: { startTime: Date.now(), latestResponse: null }
|
[profilingId]: { startTime: Date.now(), latestResponse: null },
|
||||||
}
|
},
|
||||||
}));
|
}));
|
||||||
const checkProfilingStatusLoop = async () => {
|
const checkProfilingStatusLoop = async () => {
|
||||||
const response = await checkProfilingStatus(profilingId);
|
const response = await checkProfilingStatus(profilingId);
|
||||||
this.setState(state => ({
|
this.setState((state) => ({
|
||||||
profiling: {
|
profiling: {
|
||||||
...state.profiling,
|
...state.profiling,
|
||||||
[profilingId]: {
|
[profilingId]: {
|
||||||
...state.profiling[profilingId],
|
...state.profiling[profilingId],
|
||||||
latestResponse: response
|
latestResponse: response,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}));
|
}));
|
||||||
if (response.status === "pending") {
|
if (response.status === "pending") {
|
||||||
setTimeout(checkProfilingStatusLoop, 1000);
|
setTimeout(checkProfilingStatusLoop, 1000);
|
||||||
|
@ -131,11 +133,11 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
label: "ActorTitle",
|
label: "ActorTitle",
|
||||||
value: actor.actorTitle
|
value: actor.actorTitle,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "State",
|
label: "State",
|
||||||
value: actor.state.toLocaleString()
|
value: actor.state.toLocaleString(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Resources",
|
label: "Resources",
|
||||||
|
@ -144,28 +146,28 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
|
||||||
Object.entries(actor.usedResources)
|
Object.entries(actor.usedResources)
|
||||||
.sort((a, b) => a[0].localeCompare(b[0]))
|
.sort((a, b) => a[0].localeCompare(b[0]))
|
||||||
.map(([key, value]) => `${value.toLocaleString()} ${key}`)
|
.map(([key, value]) => `${value.toLocaleString()} ${key}`)
|
||||||
.join(", ")
|
.join(", "),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Pending",
|
label: "Pending",
|
||||||
value: actor.taskQueueLength.toLocaleString()
|
value: actor.taskQueueLength.toLocaleString(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Executed",
|
label: "Executed",
|
||||||
value: actor.numExecutedTasks.toLocaleString()
|
value: actor.numExecutedTasks.toLocaleString(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "NumObjectIdsInScope",
|
label: "NumObjectIdsInScope",
|
||||||
value: actor.numObjectIdsInScope.toLocaleString()
|
value: actor.numObjectIdsInScope.toLocaleString(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "NumLocalObjects",
|
label: "NumLocalObjects",
|
||||||
value: actor.numLocalObjects.toLocaleString()
|
value: actor.numLocalObjects.toLocaleString(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "UsedLocalObjectMemory",
|
label: "UsedLocalObjectMemory",
|
||||||
value: actor.usedObjectStoreMemory.toLocaleString()
|
value: actor.usedObjectStoreMemory.toLocaleString(),
|
||||||
}
|
},
|
||||||
// {
|
// {
|
||||||
// label: "Task",
|
// label: "Task",
|
||||||
// value: actor.currentTaskFuncDesc.join(".")
|
// value: actor.currentTaskFuncDesc.join(".")
|
||||||
|
@ -174,7 +176,7 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
|
||||||
: [
|
: [
|
||||||
{
|
{
|
||||||
label: "ID",
|
label: "ID",
|
||||||
value: actor.actorId
|
value: actor.actorId,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Required resources",
|
label: "Required resources",
|
||||||
|
@ -183,8 +185,8 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
|
||||||
Object.entries(actor.requiredResources)
|
Object.entries(actor.requiredResources)
|
||||||
.sort((a, b) => a[0].localeCompare(b[0]))
|
.sort((a, b) => a[0].localeCompare(b[0]))
|
||||||
.map(([key, value]) => `${value.toLocaleString()} ${key}`)
|
.map(([key, value]) => `${value.toLocaleString()} ${key}`)
|
||||||
.join(", ")
|
.join(", "),
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
// Construct the custom message from the actor.
|
// Construct the custom message from the actor.
|
||||||
|
@ -242,7 +244,7 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)}{" "}
|
)}{" "}
|
||||||
(Profile for
|
(Profile for
|
||||||
{[10, 30, 60].map(duration => (
|
{[10, 30, 60].map((duration) => (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{" "}
|
{" "}
|
||||||
<span
|
<span
|
||||||
|
@ -268,7 +270,7 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
|
||||||
(
|
(
|
||||||
{latestResponse.status === "pending" ? (
|
{latestResponse.status === "pending" ? (
|
||||||
`Profiling for ${Math.round(
|
`Profiling for ${Math.round(
|
||||||
(Date.now() - startTime) / 1000
|
(Date.now() - startTime) / 1000,
|
||||||
)}s...`
|
)}s...`
|
||||||
) : latestResponse.status === "finished" ? (
|
) : latestResponse.status === "finished" ? (
|
||||||
<a
|
<a
|
||||||
|
@ -281,12 +283,10 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
|
||||||
</a>
|
</a>
|
||||||
) : latestResponse.status === "error" ? (
|
) : latestResponse.status === "error" ? (
|
||||||
`Profiling error: ${latestResponse.error.trim()}`
|
`Profiling error: ${latestResponse.error.trim()}`
|
||||||
) : (
|
) : undefined}
|
||||||
undefined
|
|
||||||
)}
|
|
||||||
){" "}
|
){" "}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
) : actor.invalidStateType === "infeasibleActor" ? (
|
) : actor.invalidStateType === "infeasibleActor" ? (
|
||||||
|
@ -310,7 +310,7 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
|
||||||
{label}: {value}
|
{label}: {value}
|
||||||
</span>{" "}
|
</span>{" "}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
</Typography>
|
</Typography>
|
||||||
{actor.state !== -1 && (
|
{actor.state !== -1 && (
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import { createStyles, Theme, withStyles, WithStyles } from "@material-ui/core";
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { RayletInfoResponse } from "../../../api";
|
import { RayletInfoResponse } from "../../../api";
|
||||||
import Actor from "./Actor";
|
import Actor from "./Actor";
|
||||||
|
|
||||||
const styles = (theme: Theme) => createStyles({});
|
const styles = (theme: Theme) => createStyles({});
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
actors: RayletInfoResponse["actors"];
|
actors: RayletInfoResponse["actors"];
|
||||||
}
|
};
|
||||||
|
|
||||||
class Actors extends React.Component<Props & WithStyles<typeof styles>> {
|
class Actors extends React.Component<Props & WithStyles<typeof styles>> {
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import {
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
createStyles,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
Theme,
|
||||||
import Typography from "@material-ui/core/Typography";
|
Typography,
|
||||||
|
WithStyles,
|
||||||
|
withStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import WarningRoundedIcon from "@material-ui/icons/WarningRounded";
|
import WarningRoundedIcon from "@material-ui/icons/WarningRounded";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
@ -12,16 +15,16 @@ const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
warning: {
|
warning: {
|
||||||
fontSize: "0.8125rem",
|
fontSize: "0.8125rem",
|
||||||
marginBottom: theme.spacing(2)
|
marginBottom: theme.spacing(2),
|
||||||
},
|
},
|
||||||
warningIcon: {
|
warningIcon: {
|
||||||
fontSize: "1.25em",
|
fontSize: "1.25em",
|
||||||
verticalAlign: "text-bottom"
|
verticalAlign: "text-bottom",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = (state: StoreState) => ({
|
const mapStateToProps = (state: StoreState) => ({
|
||||||
rayletInfo: state.dashboard.rayletInfo
|
rayletInfo: state.dashboard.rayletInfo,
|
||||||
});
|
});
|
||||||
|
|
||||||
class LogicalView extends React.Component<
|
class LogicalView extends React.Component<
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import {
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
createStyles,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
Table,
|
||||||
import Table from "@material-ui/core/Table";
|
TableBody,
|
||||||
import TableBody from "@material-ui/core/TableBody";
|
TableCell,
|
||||||
import TableCell from "@material-ui/core/TableCell";
|
TableHead,
|
||||||
import TableHead from "@material-ui/core/TableHead";
|
TableRow,
|
||||||
import TableRow from "@material-ui/core/TableRow";
|
Theme,
|
||||||
import Typography from "@material-ui/core/Typography";
|
Typography,
|
||||||
|
withStyles,
|
||||||
|
WithStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { StoreState } from "../../../store";
|
import { StoreState } from "../../../store";
|
||||||
|
@ -18,33 +21,33 @@ import TotalRow from "./TotalRow";
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
table: {
|
table: {
|
||||||
marginTop: theme.spacing(1)
|
marginTop: theme.spacing(1),
|
||||||
},
|
},
|
||||||
cell: {
|
cell: {
|
||||||
padding: theme.spacing(1),
|
padding: theme.spacing(1),
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
"&:last-child": {
|
"&:last-child": {
|
||||||
paddingRight: theme.spacing(1)
|
paddingRight: theme.spacing(1),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = (state: StoreState) => ({
|
const mapStateToProps = (state: StoreState) => ({
|
||||||
nodeInfo: state.dashboard.nodeInfo,
|
nodeInfo: state.dashboard.nodeInfo,
|
||||||
rayletInfo: state.dashboard.rayletInfo
|
rayletInfo: state.dashboard.rayletInfo,
|
||||||
});
|
});
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
logDialog: { hostname: string; pid: number | null } | null;
|
logDialog: { hostname: string; pid: number | null } | null;
|
||||||
errorDialog: { hostname: string; pid: number | null } | null;
|
errorDialog: { hostname: string; pid: number | null } | null;
|
||||||
}
|
};
|
||||||
|
|
||||||
class NodeInfo extends React.Component<
|
class NodeInfo extends React.Component<
|
||||||
WithStyles<typeof styles> & ReturnType<typeof mapStateToProps>
|
WithStyles<typeof styles> & ReturnType<typeof mapStateToProps>
|
||||||
> {
|
> {
|
||||||
state: State = {
|
state: State = {
|
||||||
logDialog: null,
|
logDialog: null,
|
||||||
errorDialog: null
|
errorDialog: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
setLogDialog = (hostname: string, pid: number | null) => {
|
setLogDialog = (hostname: string, pid: number | null) => {
|
||||||
|
@ -135,7 +138,7 @@ class NodeInfo extends React.Component<
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{nodeInfo.clients.map(client => (
|
{nodeInfo.clients.map((client) => (
|
||||||
<NodeRowGroup
|
<NodeRowGroup
|
||||||
key={client.ip}
|
key={client.ip}
|
||||||
node={client}
|
node={client}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import {
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
createStyles,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
TableCell,
|
||||||
import TableCell from "@material-ui/core/TableCell";
|
TableRow,
|
||||||
import TableRow from "@material-ui/core/TableRow";
|
Theme,
|
||||||
|
withStyles,
|
||||||
|
WithStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import AddIcon from "@material-ui/icons/Add";
|
import AddIcon from "@material-ui/icons/Add";
|
||||||
import RemoveIcon from "@material-ui/icons/Remove";
|
import RemoveIcon from "@material-ui/icons/Remove";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
|
@ -25,27 +28,27 @@ const styles = (theme: Theme) =>
|
||||||
padding: theme.spacing(1),
|
padding: theme.spacing(1),
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
"&:last-child": {
|
"&:last-child": {
|
||||||
paddingRight: theme.spacing(1)
|
paddingRight: theme.spacing(1),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
expandCollapseCell: {
|
expandCollapseCell: {
|
||||||
cursor: "pointer"
|
cursor: "pointer",
|
||||||
},
|
},
|
||||||
expandCollapseIcon: {
|
expandCollapseIcon: {
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
fontSize: "1.5em",
|
fontSize: "1.5em",
|
||||||
verticalAlign: "middle"
|
verticalAlign: "middle",
|
||||||
},
|
},
|
||||||
extraInfo: {
|
extraInfo: {
|
||||||
fontFamily: "SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace",
|
fontFamily: "SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace",
|
||||||
whiteSpace: "pre"
|
whiteSpace: "pre",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
type ArrayType<T> = T extends Array<infer U> ? U : never;
|
type ArrayType<T> = T extends Array<infer U> ? U : never;
|
||||||
type Node = ArrayType<NodeInfoResponse["clients"]>;
|
type Node = ArrayType<NodeInfoResponse["clients"]>;
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
node: Node;
|
node: Node;
|
||||||
raylet: RayletInfoResponse["nodes"][keyof RayletInfoResponse["nodes"]] | null;
|
raylet: RayletInfoResponse["nodes"][keyof RayletInfoResponse["nodes"]] | null;
|
||||||
logCounts: {
|
logCounts: {
|
||||||
|
@ -59,23 +62,23 @@ interface Props {
|
||||||
setLogDialog: (hostname: string, pid: number | null) => void;
|
setLogDialog: (hostname: string, pid: number | null) => void;
|
||||||
setErrorDialog: (hostname: string, pid: number | null) => void;
|
setErrorDialog: (hostname: string, pid: number | null) => void;
|
||||||
initialExpanded: boolean;
|
initialExpanded: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
expanded: boolean;
|
expanded: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
class NodeRowGroup extends React.Component<
|
class NodeRowGroup extends React.Component<
|
||||||
Props & WithStyles<typeof styles>,
|
Props & WithStyles<typeof styles>,
|
||||||
State
|
State
|
||||||
> {
|
> {
|
||||||
state: State = {
|
state: State = {
|
||||||
expanded: this.props.initialExpanded
|
expanded: this.props.initialExpanded,
|
||||||
};
|
};
|
||||||
|
|
||||||
toggleExpand = () => {
|
toggleExpand = () => {
|
||||||
this.setState(state => ({
|
this.setState((state) => ({
|
||||||
expanded: !state.expanded
|
expanded: !state.expanded,
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,7 +90,7 @@ class NodeRowGroup extends React.Component<
|
||||||
logCounts,
|
logCounts,
|
||||||
errorCounts,
|
errorCounts,
|
||||||
setLogDialog,
|
setLogDialog,
|
||||||
setErrorDialog
|
setErrorDialog,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { expanded } = this.state;
|
const { expanded } = this.state;
|
||||||
|
|
||||||
|
@ -102,12 +105,12 @@ class NodeRowGroup extends React.Component<
|
||||||
{ NodeFeature: NodeReceived, WorkerFeature: WorkerReceived },
|
{ NodeFeature: NodeReceived, WorkerFeature: WorkerReceived },
|
||||||
{
|
{
|
||||||
NodeFeature: makeNodeLogs(logCounts, setLogDialog),
|
NodeFeature: makeNodeLogs(logCounts, setLogDialog),
|
||||||
WorkerFeature: makeWorkerLogs(logCounts, setLogDialog)
|
WorkerFeature: makeWorkerLogs(logCounts, setLogDialog),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
NodeFeature: makeNodeErrors(errorCounts, setErrorDialog),
|
NodeFeature: makeNodeErrors(errorCounts, setErrorDialog),
|
||||||
WorkerFeature: makeWorkerErrors(errorCounts, setErrorDialog)
|
WorkerFeature: makeWorkerErrors(errorCounts, setErrorDialog),
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import {
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
createStyles,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
TableCell,
|
||||||
import TableCell from "@material-ui/core/TableCell";
|
TableRow,
|
||||||
import TableRow from "@material-ui/core/TableRow";
|
Theme,
|
||||||
|
WithStyles,
|
||||||
|
withStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import LayersIcon from "@material-ui/icons/Layers";
|
import LayersIcon from "@material-ui/icons/Layers";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { NodeInfoResponse } from "../../../api";
|
import { NodeInfoResponse } from "../../../api";
|
||||||
|
@ -26,17 +29,17 @@ const styles = (theme: Theme) =>
|
||||||
padding: theme.spacing(1),
|
padding: theme.spacing(1),
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
"&:last-child": {
|
"&:last-child": {
|
||||||
paddingRight: theme.spacing(1)
|
paddingRight: theme.spacing(1),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
totalIcon: {
|
totalIcon: {
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
fontSize: "1.5em",
|
fontSize: "1.5em",
|
||||||
verticalAlign: "middle"
|
verticalAlign: "middle",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
nodes: NodeInfoResponse["clients"];
|
nodes: NodeInfoResponse["clients"];
|
||||||
logCounts: {
|
logCounts: {
|
||||||
[ip: string]: {
|
[ip: string]: {
|
||||||
|
@ -50,7 +53,7 @@ interface Props {
|
||||||
total: number;
|
total: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
class TotalRow extends React.Component<Props & WithStyles<typeof styles>> {
|
class TotalRow extends React.Component<Props & WithStyles<typeof styles>> {
|
||||||
render() {
|
render() {
|
||||||
|
@ -66,7 +69,7 @@ class TotalRow extends React.Component<Props & WithStyles<typeof styles>> {
|
||||||
{ ClusterFeature: ClusterSent },
|
{ ClusterFeature: ClusterSent },
|
||||||
{ ClusterFeature: ClusterReceived },
|
{ ClusterFeature: ClusterReceived },
|
||||||
{ ClusterFeature: makeClusterLogs(logCounts) },
|
{ ClusterFeature: makeClusterLogs(logCounts) },
|
||||||
{ ClusterFeature: makeClusterErrors(errorCounts) }
|
{ ClusterFeature: makeClusterErrors(errorCounts) },
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
import {
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
createStyles,
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
fade,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
Theme,
|
||||||
import Typography from "@material-ui/core/Typography";
|
Typography,
|
||||||
|
withStyles,
|
||||||
|
WithStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { ErrorsResponse, getErrors } from "../../../../../api";
|
import { ErrorsResponse, getErrors } from "../../../../../api";
|
||||||
import DialogWithTitle from "../../../../../common/DialogWithTitle";
|
import DialogWithTitle from "../../../../../common/DialogWithTitle";
|
||||||
|
@ -13,7 +16,7 @@ const styles = (theme: Theme) =>
|
||||||
header: {
|
header: {
|
||||||
lineHeight: 1,
|
lineHeight: 1,
|
||||||
marginBottom: theme.spacing(3),
|
marginBottom: theme.spacing(3),
|
||||||
marginTop: theme.spacing(3)
|
marginTop: theme.spacing(3),
|
||||||
},
|
},
|
||||||
error: {
|
error: {
|
||||||
backgroundColor: fade(theme.palette.error.main, 0.04),
|
backgroundColor: fade(theme.palette.error.main, 0.04),
|
||||||
|
@ -21,29 +24,29 @@ const styles = (theme: Theme) =>
|
||||||
borderLeftStyle: "solid",
|
borderLeftStyle: "solid",
|
||||||
borderLeftWidth: 2,
|
borderLeftWidth: 2,
|
||||||
marginTop: theme.spacing(3),
|
marginTop: theme.spacing(3),
|
||||||
padding: theme.spacing(2)
|
padding: theme.spacing(2),
|
||||||
},
|
},
|
||||||
timestamp: {
|
timestamp: {
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
marginBottom: theme.spacing(1)
|
marginBottom: theme.spacing(1),
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
clearErrorDialog: () => void;
|
clearErrorDialog: () => void;
|
||||||
hostname: string;
|
hostname: string;
|
||||||
pid: number | null;
|
pid: number | null;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
result: ErrorsResponse | null;
|
result: ErrorsResponse | null;
|
||||||
error: string | null;
|
error: string | null;
|
||||||
}
|
};
|
||||||
|
|
||||||
class Errors extends React.Component<Props & WithStyles<typeof styles>, State> {
|
class Errors extends React.Component<Props & WithStyles<typeof styles>, State> {
|
||||||
state: State = {
|
state: State = {
|
||||||
result: null,
|
result: null,
|
||||||
error: null
|
error: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
import {
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
createStyles,
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
fade,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
Theme,
|
||||||
import Typography from "@material-ui/core/Typography";
|
Typography,
|
||||||
|
WithStyles,
|
||||||
|
withStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { getLogs, LogsResponse } from "../../../../../api";
|
import { getLogs, LogsResponse } from "../../../../../api";
|
||||||
import DialogWithTitle from "../../../../../common/DialogWithTitle";
|
import DialogWithTitle from "../../../../../common/DialogWithTitle";
|
||||||
|
@ -13,32 +16,32 @@ const styles = (theme: Theme) =>
|
||||||
header: {
|
header: {
|
||||||
lineHeight: 1,
|
lineHeight: 1,
|
||||||
marginBottom: theme.spacing(3),
|
marginBottom: theme.spacing(3),
|
||||||
marginTop: theme.spacing(3)
|
marginTop: theme.spacing(3),
|
||||||
},
|
},
|
||||||
log: {
|
log: {
|
||||||
backgroundColor: fade(theme.palette.primary.main, 0.04),
|
backgroundColor: fade(theme.palette.primary.main, 0.04),
|
||||||
borderLeftColor: theme.palette.primary.main,
|
borderLeftColor: theme.palette.primary.main,
|
||||||
borderLeftStyle: "solid",
|
borderLeftStyle: "solid",
|
||||||
borderLeftWidth: 2,
|
borderLeftWidth: 2,
|
||||||
padding: theme.spacing(2)
|
padding: theme.spacing(2),
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
clearLogDialog: () => void;
|
clearLogDialog: () => void;
|
||||||
hostname: string;
|
hostname: string;
|
||||||
pid: number | null;
|
pid: number | null;
|
||||||
}
|
};
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
result: LogsResponse | null;
|
result: LogsResponse | null;
|
||||||
error: string | null;
|
error: string | null;
|
||||||
}
|
};
|
||||||
|
|
||||||
class Logs extends React.Component<Props & WithStyles<typeof styles>, State> {
|
class Logs extends React.Component<Props & WithStyles<typeof styles>, State> {
|
||||||
state: State = {
|
state: State = {
|
||||||
result: null,
|
result: null,
|
||||||
error: null
|
error: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
|
|
|
@ -3,14 +3,14 @@ import UsageBar from "../../../../common/UsageBar";
|
||||||
import {
|
import {
|
||||||
ClusterFeatureComponent,
|
ClusterFeatureComponent,
|
||||||
NodeFeatureComponent,
|
NodeFeatureComponent,
|
||||||
WorkerFeatureComponent
|
WorkerFeatureComponent,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
const getWeightedAverage = (
|
const getWeightedAverage = (
|
||||||
input: {
|
input: {
|
||||||
weight: number;
|
weight: number;
|
||||||
value: number;
|
value: number;
|
||||||
}[]
|
}[],
|
||||||
) => {
|
) => {
|
||||||
if (input.length === 0) {
|
if (input.length === 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -27,7 +27,7 @@ const getWeightedAverage = (
|
||||||
|
|
||||||
export const ClusterCPU: ClusterFeatureComponent = ({ nodes }) => {
|
export const ClusterCPU: ClusterFeatureComponent = ({ nodes }) => {
|
||||||
const cpuWeightedAverage = getWeightedAverage(
|
const cpuWeightedAverage = getWeightedAverage(
|
||||||
nodes.map(node => ({ weight: node.cpus[0], value: node.cpu }))
|
nodes.map((node) => ({ weight: node.cpus[0], value: node.cpu })),
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div style={{ minWidth: 60 }}>
|
<div style={{ minWidth: 60 }}>
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import Typography from "@material-ui/core/Typography";
|
import { Typography } from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { formatUsage } from "../../../../common/formatUtils";
|
import { formatUsage } from "../../../../common/formatUtils";
|
||||||
import UsageBar from "../../../../common/UsageBar";
|
import UsageBar from "../../../../common/UsageBar";
|
||||||
import {
|
import {
|
||||||
ClusterFeatureComponent,
|
ClusterFeatureComponent,
|
||||||
NodeFeatureComponent,
|
NodeFeatureComponent,
|
||||||
WorkerFeatureComponent
|
WorkerFeatureComponent,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export const ClusterDisk: ClusterFeatureComponent = ({ nodes }) => {
|
export const ClusterDisk: ClusterFeatureComponent = ({ nodes }) => {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import Typography from "@material-ui/core/Typography";
|
import { Typography } from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import SpanButton from "../../../../common/SpanButton";
|
import SpanButton from "../../../../common/SpanButton";
|
||||||
import {
|
import {
|
||||||
ClusterFeatureComponent,
|
ClusterFeatureComponent,
|
||||||
NodeFeatureComponent,
|
NodeFeatureComponent,
|
||||||
WorkerFeatureComponent
|
WorkerFeatureComponent,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export const makeClusterErrors = (errorCounts: {
|
export const makeClusterErrors = (errorCounts: {
|
||||||
|
@ -38,7 +38,7 @@ export const makeNodeErrors = (
|
||||||
perWorker: { [pid: string]: number };
|
perWorker: { [pid: string]: number };
|
||||||
total: number;
|
total: number;
|
||||||
},
|
},
|
||||||
setErrorDialog: (hostname: string, pid: number | null) => void
|
setErrorDialog: (hostname: string, pid: number | null) => void,
|
||||||
): NodeFeatureComponent => ({ node }) =>
|
): NodeFeatureComponent => ({ node }) =>
|
||||||
errorCounts.total === 0 ? (
|
errorCounts.total === 0 ? (
|
||||||
<Typography color="textSecondary" component="span" variant="inherit">
|
<Typography color="textSecondary" component="span" variant="inherit">
|
||||||
|
@ -55,7 +55,7 @@ export const makeWorkerErrors = (
|
||||||
perWorker: { [pid: string]: number };
|
perWorker: { [pid: string]: number };
|
||||||
total: number;
|
total: number;
|
||||||
},
|
},
|
||||||
setErrorDialog: (hostname: string, pid: number | null) => void
|
setErrorDialog: (hostname: string, pid: number | null) => void,
|
||||||
): WorkerFeatureComponent => ({ node, worker }) =>
|
): WorkerFeatureComponent => ({ node, worker }) =>
|
||||||
errorCounts.perWorker[worker.pid] === 0 ? (
|
errorCounts.perWorker[worker.pid] === 0 ? (
|
||||||
<Typography color="textSecondary" component="span" variant="inherit">
|
<Typography color="textSecondary" component="span" variant="inherit">
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from "react";
|
||||||
import {
|
import {
|
||||||
ClusterFeatureComponent,
|
ClusterFeatureComponent,
|
||||||
NodeFeatureComponent,
|
NodeFeatureComponent,
|
||||||
WorkerFeatureComponent
|
WorkerFeatureComponent,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export const ClusterHost: ClusterFeatureComponent = ({ nodes }) => (
|
export const ClusterHost: ClusterFeatureComponent = ({ nodes }) => (
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import Typography from "@material-ui/core/Typography";
|
import { Typography } from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import SpanButton from "../../../../common/SpanButton";
|
import SpanButton from "../../../../common/SpanButton";
|
||||||
import {
|
import {
|
||||||
ClusterFeatureComponent,
|
ClusterFeatureComponent,
|
||||||
NodeFeatureComponent,
|
NodeFeatureComponent,
|
||||||
WorkerFeatureComponent
|
WorkerFeatureComponent,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export const makeClusterLogs = (logCounts: {
|
export const makeClusterLogs = (logCounts: {
|
||||||
|
@ -37,7 +37,7 @@ export const makeNodeLogs = (
|
||||||
perWorker: { [pid: string]: number };
|
perWorker: { [pid: string]: number };
|
||||||
total: number;
|
total: number;
|
||||||
},
|
},
|
||||||
setLogDialog: (hostname: string, pid: number | null) => void
|
setLogDialog: (hostname: string, pid: number | null) => void,
|
||||||
): NodeFeatureComponent => ({ node }) =>
|
): NodeFeatureComponent => ({ node }) =>
|
||||||
logCounts.total === 0 ? (
|
logCounts.total === 0 ? (
|
||||||
<Typography color="textSecondary" component="span" variant="inherit">
|
<Typography color="textSecondary" component="span" variant="inherit">
|
||||||
|
@ -55,7 +55,7 @@ export const makeWorkerLogs = (
|
||||||
perWorker: { [pid: string]: number };
|
perWorker: { [pid: string]: number };
|
||||||
total: number;
|
total: number;
|
||||||
},
|
},
|
||||||
setLogDialog: (hostname: string, pid: number | null) => void
|
setLogDialog: (hostname: string, pid: number | null) => void,
|
||||||
): WorkerFeatureComponent => ({ node, worker }) =>
|
): WorkerFeatureComponent => ({ node, worker }) =>
|
||||||
logCounts.perWorker[worker.pid] === 0 ? (
|
logCounts.perWorker[worker.pid] === 0 ? (
|
||||||
<Typography color="textSecondary" component="span" variant="inherit">
|
<Typography color="textSecondary" component="span" variant="inherit">
|
||||||
|
|
|
@ -4,7 +4,7 @@ import UsageBar from "../../../../common/UsageBar";
|
||||||
import {
|
import {
|
||||||
ClusterFeatureComponent,
|
ClusterFeatureComponent,
|
||||||
NodeFeatureComponent,
|
NodeFeatureComponent,
|
||||||
WorkerFeatureComponent
|
WorkerFeatureComponent,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export const ClusterRAM: ClusterFeatureComponent = ({ nodes }) => {
|
export const ClusterRAM: ClusterFeatureComponent = ({ nodes }) => {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import Typography from "@material-ui/core/Typography";
|
import { Typography } from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { formatByteAmount } from "../../../../common/formatUtils";
|
import { formatByteAmount } from "../../../../common/formatUtils";
|
||||||
import {
|
import {
|
||||||
ClusterFeatureComponent,
|
ClusterFeatureComponent,
|
||||||
NodeFeatureComponent,
|
NodeFeatureComponent,
|
||||||
WorkerFeatureComponent
|
WorkerFeatureComponent,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export const ClusterReceived: ClusterFeatureComponent = ({ nodes }) => {
|
export const ClusterReceived: ClusterFeatureComponent = ({ nodes }) => {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import Typography from "@material-ui/core/Typography";
|
import { Typography } from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { formatByteAmount } from "../../../../common/formatUtils";
|
import { formatByteAmount } from "../../../../common/formatUtils";
|
||||||
import {
|
import {
|
||||||
ClusterFeatureComponent,
|
ClusterFeatureComponent,
|
||||||
NodeFeatureComponent,
|
NodeFeatureComponent,
|
||||||
WorkerFeatureComponent
|
WorkerFeatureComponent,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export const ClusterSent: ClusterFeatureComponent = ({ nodes }) => {
|
export const ClusterSent: ClusterFeatureComponent = ({ nodes }) => {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import Typography from "@material-ui/core/Typography";
|
import { Typography } from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { formatDuration } from "../../../../common/formatUtils";
|
import { formatDuration } from "../../../../common/formatUtils";
|
||||||
import {
|
import {
|
||||||
ClusterFeatureComponent,
|
ClusterFeatureComponent,
|
||||||
NodeFeatureComponent,
|
NodeFeatureComponent,
|
||||||
WorkerFeatureComponent
|
WorkerFeatureComponent,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
const getUptime = (bootTime: number) => Date.now() / 1000 - bootTime;
|
const getUptime = (bootTime: number) => Date.now() / 1000 - bootTime;
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from "react";
|
||||||
import {
|
import {
|
||||||
ClusterFeatureComponent,
|
ClusterFeatureComponent,
|
||||||
NodeFeatureComponent,
|
NodeFeatureComponent,
|
||||||
WorkerFeatureComponent
|
WorkerFeatureComponent,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export const ClusterWorkers: ClusterFeatureComponent = ({ nodes }) => {
|
export const ClusterWorkers: ClusterFeatureComponent = ({ nodes }) => {
|
||||||
|
|
|
@ -10,11 +10,11 @@ type NodeFeatureData = { node: Node };
|
||||||
type WorkerFeatureData = { node: Node; worker: Worker };
|
type WorkerFeatureData = { node: Node; worker: Worker };
|
||||||
|
|
||||||
export type ClusterFeatureComponent = (
|
export type ClusterFeatureComponent = (
|
||||||
data: ClusterFeatureData
|
data: ClusterFeatureData,
|
||||||
) => React.ReactElement;
|
) => React.ReactElement;
|
||||||
export type NodeFeatureComponent = (
|
export type NodeFeatureComponent = (
|
||||||
data: NodeFeatureData
|
data: NodeFeatureData,
|
||||||
) => React.ReactElement;
|
) => React.ReactElement;
|
||||||
export type WorkerFeatureComponent = (
|
export type WorkerFeatureComponent = (
|
||||||
data: WorkerFeatureData
|
data: WorkerFeatureData,
|
||||||
) => React.ReactElement;
|
) => React.ReactElement;
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import {
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
createStyles,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
Table,
|
||||||
import Table from "@material-ui/core/Table";
|
TableBody,
|
||||||
import TableBody from "@material-ui/core/TableBody";
|
TableCell,
|
||||||
import TableCell from "@material-ui/core/TableCell";
|
TableHead,
|
||||||
import TableHead from "@material-ui/core/TableHead";
|
TableRow,
|
||||||
import TableRow from "@material-ui/core/TableRow";
|
Theme,
|
||||||
import Typography from "@material-ui/core/Typography";
|
Typography,
|
||||||
|
withStyles,
|
||||||
|
WithStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
@ -18,7 +21,7 @@ const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
table: {
|
table: {
|
||||||
marginTop: theme.spacing(1),
|
marginTop: theme.spacing(1),
|
||||||
width: "auto"
|
width: "auto",
|
||||||
},
|
},
|
||||||
cell: {
|
cell: {
|
||||||
paddingTop: theme.spacing(1),
|
paddingTop: theme.spacing(1),
|
||||||
|
@ -27,16 +30,16 @@ const styles = (theme: Theme) =>
|
||||||
paddingRight: theme.spacing(3),
|
paddingRight: theme.spacing(3),
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
"&:last-child": {
|
"&:last-child": {
|
||||||
paddingRight: theme.spacing(3)
|
paddingRight: theme.spacing(3),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
key: {
|
key: {
|
||||||
color: theme.palette.text.secondary
|
color: theme.palette.text.secondary,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = (state: StoreState) => ({
|
const mapStateToProps = (state: StoreState) => ({
|
||||||
rayConfig: state.dashboard.rayConfig
|
rayConfig: state.dashboard.rayConfig,
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = dashboardActions;
|
const mapDispatchToProps = dashboardActions;
|
||||||
|
@ -74,34 +77,34 @@ class RayConfig extends React.Component<
|
||||||
const formattedRayConfig = [
|
const formattedRayConfig = [
|
||||||
{
|
{
|
||||||
key: "Autoscaling mode",
|
key: "Autoscaling mode",
|
||||||
value: rayConfig.autoscaling_mode
|
value: rayConfig.autoscaling_mode,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "Head node type",
|
key: "Head node type",
|
||||||
value: rayConfig.head_type
|
value: rayConfig.head_type,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "Worker node type",
|
key: "Worker node type",
|
||||||
value: rayConfig.worker_type
|
value: rayConfig.worker_type,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "Min worker nodes",
|
key: "Min worker nodes",
|
||||||
value: rayConfig.min_workers
|
value: rayConfig.min_workers,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "Initial worker nodes",
|
key: "Initial worker nodes",
|
||||||
value: rayConfig.initial_workers
|
value: rayConfig.initial_workers,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "Max worker nodes",
|
key: "Max worker nodes",
|
||||||
value: rayConfig.max_workers
|
value: rayConfig.max_workers,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "Idle timeout",
|
key: "Idle timeout",
|
||||||
value: `${rayConfig.idle_timeout_minutes} ${
|
value: `${rayConfig.idle_timeout_minutes} ${
|
||||||
rayConfig.idle_timeout_minutes === 1 ? "minute" : "minutes"
|
rayConfig.idle_timeout_minutes === 1 ? "minute" : "minutes"
|
||||||
}`
|
}`,
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -132,5 +135,5 @@ class RayConfig extends React.Component<
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
mapDispatchToProps
|
mapDispatchToProps,
|
||||||
)(withStyles(styles)(RayConfig));
|
)(withStyles(styles)(RayConfig));
|
||||||
|
|
|
@ -3,13 +3,13 @@ import {
|
||||||
NodeInfoResponse,
|
NodeInfoResponse,
|
||||||
RayConfigResponse,
|
RayConfigResponse,
|
||||||
RayletInfoResponse,
|
RayletInfoResponse,
|
||||||
|
TuneAvailabilityResponse,
|
||||||
TuneJobResponse,
|
TuneJobResponse,
|
||||||
TuneAvailabilityResponse
|
|
||||||
} from "../../api";
|
} from "../../api";
|
||||||
|
|
||||||
const name = "dashboard";
|
const name = "dashboard";
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
tab: number;
|
tab: number;
|
||||||
rayConfig: RayConfigResponse | null;
|
rayConfig: RayConfigResponse | null;
|
||||||
nodeInfo: NodeInfoResponse | null;
|
nodeInfo: NodeInfoResponse | null;
|
||||||
|
@ -18,7 +18,7 @@ interface State {
|
||||||
tuneAvailability: boolean;
|
tuneAvailability: boolean;
|
||||||
lastUpdatedAt: number | null;
|
lastUpdatedAt: number | null;
|
||||||
error: string | null;
|
error: string | null;
|
||||||
}
|
};
|
||||||
|
|
||||||
const initialState: State = {
|
const initialState: State = {
|
||||||
tab: 0,
|
tab: 0,
|
||||||
|
@ -28,7 +28,7 @@ const initialState: State = {
|
||||||
tuneInfo: null,
|
tuneInfo: null,
|
||||||
tuneAvailability: false,
|
tuneAvailability: false,
|
||||||
lastUpdatedAt: null,
|
lastUpdatedAt: null,
|
||||||
error: null
|
error: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const slice = createSlice({
|
const slice = createSlice({
|
||||||
|
@ -46,7 +46,7 @@ const slice = createSlice({
|
||||||
action: PayloadAction<{
|
action: PayloadAction<{
|
||||||
nodeInfo: NodeInfoResponse;
|
nodeInfo: NodeInfoResponse;
|
||||||
rayletInfo: RayletInfoResponse;
|
rayletInfo: RayletInfoResponse;
|
||||||
}>
|
}>,
|
||||||
) => {
|
) => {
|
||||||
state.nodeInfo = action.payload.nodeInfo;
|
state.nodeInfo = action.payload.nodeInfo;
|
||||||
state.rayletInfo = action.payload.rayletInfo;
|
state.rayletInfo = action.payload.rayletInfo;
|
||||||
|
@ -60,7 +60,7 @@ const slice = createSlice({
|
||||||
state,
|
state,
|
||||||
action: PayloadAction<{
|
action: PayloadAction<{
|
||||||
tuneAvailability: TuneAvailabilityResponse;
|
tuneAvailability: TuneAvailabilityResponse;
|
||||||
}>
|
}>,
|
||||||
) => {
|
) => {
|
||||||
const tuneAvailability =
|
const tuneAvailability =
|
||||||
action.payload.tuneAvailability === null
|
action.payload.tuneAvailability === null
|
||||||
|
@ -71,8 +71,8 @@ const slice = createSlice({
|
||||||
},
|
},
|
||||||
setError: (state, action: PayloadAction<string | null>) => {
|
setError: (state, action: PayloadAction<string | null>) => {
|
||||||
state.error = action.payload;
|
state.error = action.payload;
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const dashboardActions = slice.actions;
|
export const dashboardActions = slice.actions;
|
||||||
|
|
|
@ -1,46 +1,49 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import {
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
createStyles,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
Tab,
|
||||||
|
Tabs,
|
||||||
|
Theme,
|
||||||
|
Typography,
|
||||||
|
WithStyles,
|
||||||
|
withStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
|
import WarningRoundedIcon from "@material-ui/icons/WarningRounded";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { getTuneInfo } from "../../../api";
|
import { getTuneInfo } from "../../../api";
|
||||||
import { StoreState } from "../../../store";
|
import { StoreState } from "../../../store";
|
||||||
import { dashboardActions } from "../state";
|
import { dashboardActions } from "../state";
|
||||||
import Typography from "@material-ui/core/Typography";
|
|
||||||
import WarningRoundedIcon from "@material-ui/icons/WarningRounded";
|
|
||||||
import Tab from "@material-ui/core/Tab";
|
|
||||||
import Tabs from "@material-ui/core/Tabs";
|
|
||||||
import TuneTable from "./TuneTable";
|
import TuneTable from "./TuneTable";
|
||||||
import TuneTensorBoard from "./TuneTensorBoard";
|
import TuneTensorBoard from "./TuneTensorBoard";
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
root: {
|
root: {
|
||||||
backgroundColor: theme.palette.background.paper
|
backgroundColor: theme.palette.background.paper,
|
||||||
},
|
},
|
||||||
tabs: {
|
tabs: {
|
||||||
borderBottomColor: theme.palette.divider,
|
borderBottomColor: theme.palette.divider,
|
||||||
borderBottomStyle: "solid",
|
borderBottomStyle: "solid",
|
||||||
borderBottomWidth: 1
|
borderBottomWidth: 1,
|
||||||
},
|
},
|
||||||
warning: {
|
warning: {
|
||||||
fontSize: "0.8125rem"
|
fontSize: "0.8125rem",
|
||||||
},
|
},
|
||||||
warningIcon: {
|
warningIcon: {
|
||||||
fontSize: "1.25em",
|
fontSize: "1.25em",
|
||||||
verticalAlign: "text-bottom"
|
verticalAlign: "text-bottom",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = (state: StoreState) => ({
|
const mapStateToProps = (state: StoreState) => ({
|
||||||
tuneInfo: state.dashboard.tuneInfo
|
tuneInfo: state.dashboard.tuneInfo,
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = dashboardActions;
|
const mapDispatchToProps = dashboardActions;
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
tabIndex: number;
|
tabIndex: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
class Tune extends React.Component<
|
class Tune extends React.Component<
|
||||||
WithStyles<typeof styles> &
|
WithStyles<typeof styles> &
|
||||||
|
@ -51,7 +54,7 @@ class Tune extends React.Component<
|
||||||
timeout: number = 0;
|
timeout: number = 0;
|
||||||
|
|
||||||
state: State = {
|
state: State = {
|
||||||
tabIndex: 0
|
tabIndex: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
refreshTuneInfo = async () => {
|
refreshTuneInfo = async () => {
|
||||||
|
@ -75,7 +78,7 @@ class Tune extends React.Component<
|
||||||
|
|
||||||
handleTabChange = (event: React.ChangeEvent<{}>, value: number) => {
|
handleTabChange = (event: React.ChangeEvent<{}>, value: number) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
tabIndex: value
|
tabIndex: value,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -86,7 +89,7 @@ class Tune extends React.Component<
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{ label: "Table", component: TuneTable },
|
{ label: "Table", component: TuneTable },
|
||||||
{ label: "TensorBoard", component: TuneTensorBoard }
|
{ label: "TensorBoard", component: TuneTensorBoard },
|
||||||
];
|
];
|
||||||
|
|
||||||
const SelectedComponent = tabs[tabIndex].component;
|
const SelectedComponent = tabs[tabIndex].component;
|
||||||
|
@ -115,5 +118,5 @@ class Tune extends React.Component<
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
mapDispatchToProps
|
mapDispatchToProps,
|
||||||
)(withStyles(styles)(Tune));
|
)(withStyles(styles)(Tune));
|
||||||
|
|
|
@ -1,47 +1,50 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import {
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
createStyles,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TableRow,
|
||||||
|
TableSortLabel,
|
||||||
|
Theme,
|
||||||
|
withStyles,
|
||||||
|
WithStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
import { TuneTrial } from "../../../api";
|
||||||
import { StoreState } from "../../../store";
|
import { StoreState } from "../../../store";
|
||||||
import { dashboardActions } from "../state";
|
import { dashboardActions } from "../state";
|
||||||
import Table from "@material-ui/core/Table";
|
|
||||||
import TableBody from "@material-ui/core/TableBody";
|
|
||||||
import TableCell from "@material-ui/core/TableCell";
|
|
||||||
import TableHead from "@material-ui/core/TableHead";
|
|
||||||
import TableRow from "@material-ui/core/TableRow";
|
|
||||||
import TableSortLabel from "@material-ui/core/TableSortLabel";
|
|
||||||
import { TuneTrial } from "../../../api";
|
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
root: {
|
root: {
|
||||||
padding: theme.spacing(2),
|
padding: theme.spacing(2),
|
||||||
"& > :not(:first-child)": {
|
"& > :not(:first-child)": {
|
||||||
marginTop: theme.spacing(2)
|
marginTop: theme.spacing(2),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
table: {
|
table: {
|
||||||
marginTop: theme.spacing(1)
|
marginTop: theme.spacing(1),
|
||||||
},
|
},
|
||||||
cell: {
|
cell: {
|
||||||
padding: theme.spacing(1),
|
padding: theme.spacing(1),
|
||||||
textAlign: "right",
|
textAlign: "right",
|
||||||
"&:last-child": {
|
"&:last-child": {
|
||||||
paddingRight: theme.spacing(1)
|
paddingRight: theme.spacing(1),
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = (state: StoreState) => ({
|
const mapStateToProps = (state: StoreState) => ({
|
||||||
tuneInfo: state.dashboard.tuneInfo
|
tuneInfo: state.dashboard.tuneInfo,
|
||||||
});
|
});
|
||||||
|
|
||||||
interface State {
|
type State = {
|
||||||
metricParamColumn: string;
|
metricParamColumn: string;
|
||||||
ascending: boolean;
|
ascending: boolean;
|
||||||
sortedColumn: keyof TuneTrial | undefined;
|
sortedColumn: keyof TuneTrial | undefined;
|
||||||
}
|
};
|
||||||
|
|
||||||
const mapDispatchToProps = dashboardActions;
|
const mapDispatchToProps = dashboardActions;
|
||||||
|
|
||||||
|
@ -56,7 +59,7 @@ class TuneTable extends React.Component<
|
||||||
state: State = {
|
state: State = {
|
||||||
sortedColumn: undefined,
|
sortedColumn: undefined,
|
||||||
ascending: true,
|
ascending: true,
|
||||||
metricParamColumn: ""
|
metricParamColumn: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
onColumnClick = (column: keyof TuneTrial, metricParamColumn?: string) => {
|
onColumnClick = (column: keyof TuneTrial, metricParamColumn?: string) => {
|
||||||
|
@ -68,12 +71,12 @@ class TuneTable extends React.Component<
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
sortedColumn: column,
|
sortedColumn: column,
|
||||||
ascending: ascending
|
ascending: ascending,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (metricParamColumn) {
|
if (metricParamColumn) {
|
||||||
this.setState({
|
this.setState({
|
||||||
metricParamColumn: metricParamColumn
|
metricParamColumn: metricParamColumn,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -82,14 +85,11 @@ class TuneTable extends React.Component<
|
||||||
* Replaces all underscores with spaces and capitalizes all words
|
* Replaces all underscores with spaces and capitalizes all words
|
||||||
* in str
|
* in str
|
||||||
*/
|
*/
|
||||||
humanize = (str: string) => {
|
humanize = (str: string) =>
|
||||||
var i,
|
str
|
||||||
frags = str.split("_");
|
.split("_")
|
||||||
for (i = 0; i < frags.length; i++) {
|
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
||||||
frags[i] = frags[i].charAt(0).toUpperCase() + frags[i].slice(1);
|
.join(" ");
|
||||||
}
|
|
||||||
return frags.join(" ");
|
|
||||||
};
|
|
||||||
|
|
||||||
sortedCell = (name: keyof TuneTrial, chosenMetricParam?: string) => {
|
sortedCell = (name: keyof TuneTrial, chosenMetricParam?: string) => {
|
||||||
const { tuneInfo, classes } = this.props;
|
const { tuneInfo, classes } = this.props;
|
||||||
|
@ -154,11 +154,11 @@ class TuneTable extends React.Component<
|
||||||
if (sortedColumn) {
|
if (sortedColumn) {
|
||||||
if (ascending) {
|
if (ascending) {
|
||||||
trialDetails.sort((a, b) =>
|
trialDetails.sort((a, b) =>
|
||||||
getAttribute(a) > getAttribute(b) ? 1 : -1
|
getAttribute(a) > getAttribute(b) ? 1 : -1,
|
||||||
);
|
);
|
||||||
} else if (!ascending) {
|
} else if (!ascending) {
|
||||||
trialDetails.sort((a, b) =>
|
trialDetails.sort((a, b) =>
|
||||||
getAttribute(a) < getAttribute(b) ? 1 : -1
|
getAttribute(a) < getAttribute(b) ? 1 : -1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,10 +178,10 @@ class TuneTable extends React.Component<
|
||||||
|
|
||||||
const firstTrial = Object.keys(tuneInfo["trial_records"])[0];
|
const firstTrial = Object.keys(tuneInfo["trial_records"])[0];
|
||||||
const paramsDict = tuneInfo["trial_records"][firstTrial]["params"];
|
const paramsDict = tuneInfo["trial_records"][firstTrial]["params"];
|
||||||
const paramNames = Object.keys(paramsDict).filter(k => k !== "args");
|
const paramNames = Object.keys(paramsDict).filter((k) => k !== "args");
|
||||||
|
|
||||||
const metricNames = Object.keys(
|
const metricNames = Object.keys(
|
||||||
tuneInfo["trial_records"][firstTrial]["metrics"]
|
tuneInfo["trial_records"][firstTrial]["metrics"],
|
||||||
);
|
);
|
||||||
|
|
||||||
const trialDetails = this.sortedTrialRecords();
|
const trialDetails = this.sortedTrialRecords();
|
||||||
|
@ -194,9 +194,9 @@ class TuneTable extends React.Component<
|
||||||
{this.sortedCell("trial_id")}
|
{this.sortedCell("trial_id")}
|
||||||
{this.sortedCell("job_id")}
|
{this.sortedCell("job_id")}
|
||||||
{this.sortedCell("start_time")}
|
{this.sortedCell("start_time")}
|
||||||
{paramNames.map(value => this.sortedCell("params", value))}
|
{paramNames.map((value) => this.sortedCell("params", value))}
|
||||||
{this.sortedCell("status")}
|
{this.sortedCell("status")}
|
||||||
{metricNames.map(value => this.sortedCell("metrics", value))}
|
{metricNames.map((value) => this.sortedCell("metrics", value))}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
|
@ -212,7 +212,7 @@ class TuneTable extends React.Component<
|
||||||
<TableCell className={classes.cell}>
|
<TableCell className={classes.cell}>
|
||||||
{trial["start_time"]}
|
{trial["start_time"]}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
{paramNames.map(value => (
|
{paramNames.map((value) => (
|
||||||
<TableCell className={classes.cell} key={value}>
|
<TableCell className={classes.cell} key={value}>
|
||||||
{trial["params"][value]}
|
{trial["params"][value]}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
@ -221,7 +221,7 @@ class TuneTable extends React.Component<
|
||||||
{trial["status"]}
|
{trial["status"]}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
{trial["metrics"] &&
|
{trial["metrics"] &&
|
||||||
metricNames.map(value => (
|
metricNames.map((value) => (
|
||||||
<TableCell className={classes.cell} key={value}>
|
<TableCell className={classes.cell} key={value}>
|
||||||
{trial["metrics"][value]}
|
{trial["metrics"][value]}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
@ -237,5 +237,5 @@ class TuneTable extends React.Component<
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
mapDispatchToProps
|
mapDispatchToProps,
|
||||||
)(withStyles(styles)(TuneTable));
|
)(withStyles(styles)(TuneTable));
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
import { Theme } from "@material-ui/core/styles/createMuiTheme";
|
import {
|
||||||
import createStyles from "@material-ui/core/styles/createStyles";
|
createStyles,
|
||||||
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
|
Theme,
|
||||||
|
Typography,
|
||||||
|
WithStyles,
|
||||||
|
withStyles,
|
||||||
|
} from "@material-ui/core";
|
||||||
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { StoreState } from "../../../store";
|
import { StoreState } from "../../../store";
|
||||||
import { dashboardActions } from "../state";
|
import { dashboardActions } from "../state";
|
||||||
import React from "react";
|
|
||||||
import Typography from "@material-ui/core/Typography";
|
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
|
@ -13,21 +16,21 @@ const styles = (theme: Theme) =>
|
||||||
backgroundColor: theme.palette.background.paper,
|
backgroundColor: theme.palette.background.paper,
|
||||||
padding: theme.spacing(2),
|
padding: theme.spacing(2),
|
||||||
"& > :not(:first-child)": {
|
"& > :not(:first-child)": {
|
||||||
marginTop: theme.spacing(4)
|
marginTop: theme.spacing(4),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
board: {
|
board: {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "1000px",
|
height: "1000px",
|
||||||
border: "none"
|
border: "none",
|
||||||
},
|
},
|
||||||
warning: {
|
warning: {
|
||||||
fontSize: "0.8125rem"
|
fontSize: "0.8125rem",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = (state: StoreState) => ({
|
const mapStateToProps = (state: StoreState) => ({
|
||||||
error: state.dashboard.error
|
error: state.dashboard.error,
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = dashboardActions;
|
const mapDispatchToProps = dashboardActions;
|
||||||
|
@ -60,5 +63,5 @@ class TuneTensorBoard extends React.Component<
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
mapDispatchToProps
|
mapDispatchToProps,
|
||||||
)(withStyles(styles)(TuneTensorBoard));
|
)(withStyles(styles)(TuneTensorBoard));
|
||||||
|
|
|
@ -3,9 +3,9 @@ import { dashboardReducer } from "./pages/dashboard/state";
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
dashboard: dashboardReducer
|
dashboard: dashboardReducer,
|
||||||
},
|
},
|
||||||
devTools: process.env.NODE_ENV === "development"
|
devTools: process.env.NODE_ENV === "development",
|
||||||
});
|
});
|
||||||
|
|
||||||
export type StoreState = ReturnType<typeof store.getState>;
|
export type StoreState = ReturnType<typeof store.getState>;
|
||||||
|
|
Loading…
Add table
Reference in a new issue