[Dashboard] Update dependencies and add linting rules (#7779)

This commit is contained in:
Mitchell Stern 2020-03-27 16:53:49 -07:00 committed by GitHub
parent 0cfb6488a7
commit 090a8474b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 6296 additions and 3109 deletions

File diff suppressed because it is too large Load diff

View file

@ -3,27 +3,29 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@material-ui/core": "^4.3.3",
"@material-ui/icons": "^4.2.1",
"@reduxjs/toolkit": "^1.0.4",
"@types/classnames": "^2.2.9",
"@types/jest": "24.0.18",
"@types/node": "12.7.2",
"@types/react": "16.9.2",
"@types/react-dom": "16.9.0",
"@types/react-redux": "^7.1.5",
"@types/react-router-dom": "^4.3.5",
"@material-ui/core": "^4.9.7",
"@material-ui/icons": "^4.9.1",
"@reduxjs/toolkit": "^1.3.1",
"@types/classnames": "^2.2.10",
"@types/jest": "25.1.4",
"@types/node": "13.9.5",
"@types/react": "16.9.26",
"@types/react-dom": "16.9.5",
"@types/react-redux": "^7.1.7",
"@types/react-router-dom": "^5.1.3",
"classnames": "^2.2.6",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-redux": "^7.1.3",
"react-router-dom": "^5.0.1",
"react-scripts": "3.1.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-redux": "^7.2.0",
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.1",
"typeface-roboto": "0.0.75",
"typescript": "3.5.3"
"typescript": "3.8.3"
},
"devDependencies": {
"prettier": "^1.18.2"
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-prefer-arrow": "^1.1.7",
"prettier": "^2.0.2"
},
"scripts": {
"start": "react-scripts start",
@ -32,7 +34,64 @@
"eject": "react-scripts eject"
},
"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": {
"production": [

View file

@ -1,4 +1,4 @@
import CssBaseline from "@material-ui/core/CssBaseline";
import { CssBaseline } from "@material-ui/core";
import React from "react";
import { Provider } from "react-redux";
import { BrowserRouter, Route } from "react-router-dom";

View file

@ -22,7 +22,7 @@ const get = async <T>(path: string, params: { [key: string]: any }) => {
return result as T;
};
export interface RayConfigResponse {
export type RayConfigResponse = {
min_workers: number;
max_workers: number;
initial_workers: number;
@ -30,11 +30,11 @@ export interface RayConfigResponse {
idle_timeout_minutes: number;
head_type: string;
worker_type: string;
}
};
export const getRayConfig = () => get<RayConfigResponse>("/api/ray_config", {});
export interface NodeInfoResponse {
export type NodeInfoResponse = {
clients: Array<{
now: number;
hostname: string;
@ -82,11 +82,11 @@ export interface NodeInfoResponse {
[pid: string]: number;
};
};
}
};
export const getNodeInfo = () => get<NodeInfoResponse>("/api/node_info", {});
export interface RayletInfoResponse {
export type RayletInfoResponse = {
nodes: {
[ip: string]: {
extraInfo?: string;
@ -130,33 +130,33 @@ export interface RayletInfoResponse {
invalidStateType?: "infeasibleActor" | "pendingActor";
};
};
}
};
export const getRayletInfo = () =>
get<RayletInfoResponse>("/api/raylet_info", {});
export interface ErrorsResponse {
export type ErrorsResponse = {
[pid: string]: Array<{
message: string;
timestamp: number;
type: string;
}>;
}
};
export const getErrors = (hostname: string, pid: number | null) =>
get<ErrorsResponse>("/api/errors", {
hostname,
pid: pid === null ? "" : pid
pid: pid === null ? "" : pid,
});
export interface LogsResponse {
export type LogsResponse = {
[pid: string]: string[];
}
};
export const getLogs = (hostname: string, pid: number | null) =>
get<LogsResponse>("/api/logs", {
hostname,
pid: pid === null ? "" : pid
pid: pid === null ? "" : pid,
});
export type LaunchProfilingResponse = string;
@ -164,12 +164,12 @@ export type LaunchProfilingResponse = string;
export const launchProfiling = (
nodeId: string,
pid: number,
duration: number
duration: number,
) =>
get<LaunchProfilingResponse>("/api/launch_profiling", {
node_id: nodeId,
pid: pid,
duration: duration
duration: duration,
});
export type CheckProfilingStatusResponse =
@ -179,26 +179,26 @@ export type CheckProfilingStatusResponse =
export const checkProfilingStatus = (profilingId: string) =>
get<CheckProfilingStatusResponse>("/api/check_profiling_status", {
profiling_id: profilingId
profiling_id: profilingId,
});
export const getProfilingResultURL = (profilingId: string) =>
`${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 = (
actorId: string,
actorIpAddress: string,
actorPort: number
actorPort: number,
) =>
get<string>("/api/kill_actor", {
actor_id: actorId,
ip_address: actorIpAddress,
port: actorPort
port: actorPort,
});
export interface TuneTrial {
export type TuneTrial = {
date: string;
episodes_total: string;
experiment_id: string;
@ -221,17 +221,17 @@ export interface TuneTrial {
job_id: string;
params: { [key: string]: string | number };
metrics: { [key: string]: string | number };
}
};
export interface TuneJobResponse {
export type TuneJobResponse = {
trial_records: { [key: string]: TuneTrial };
}
};
export const getTuneInfo = () => get<TuneJobResponse>("/api/tune_info", {});
export interface TuneAvailabilityResponse {
export type TuneAvailabilityResponse = {
available: boolean;
}
};
export const getTuneAvailability = () =>
get<TuneAvailabilityResponse>("/api/tune_availability", {});

View file

@ -1,22 +1,25 @@
import Dialog from "@material-ui/core/Dialog";
import IconButton from "@material-ui/core/IconButton";
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import Typography from "@material-ui/core/Typography";
import {
createStyles,
Dialog,
IconButton,
Theme,
Typography,
WithStyles,
withStyles,
} from "@material-ui/core";
import CloseIcon from "@material-ui/icons/Close";
import React from "react";
const styles = (theme: Theme) =>
createStyles({
paper: {
padding: theme.spacing(3)
padding: theme.spacing(3),
},
closeButton: {
position: "absolute",
right: theme.spacing(1.5),
top: theme.spacing(1.5),
zIndex: 1
zIndex: 1,
},
title: {
borderBottomColor: theme.palette.divider,
@ -25,14 +28,14 @@ const styles = (theme: Theme) =>
fontSize: "1.5rem",
lineHeight: 1,
marginBottom: theme.spacing(3),
paddingBottom: theme.spacing(3)
}
paddingBottom: theme.spacing(3),
},
});
interface Props {
type Props = {
handleClose: () => void;
title: string;
}
};
class DialogWithTitle extends React.Component<
Props & WithStyles<typeof styles>

View file

@ -1,25 +1,28 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableRow from "@material-ui/core/TableRow";
import {
createStyles,
Table,
TableBody,
TableCell,
TableRow,
Theme,
withStyles,
WithStyles,
} from "@material-ui/core";
import classNames from "classnames";
import React from "react";
const styles = (theme: Theme) =>
createStyles({
root: {
overflowX: "auto"
overflowX: "auto",
},
cell: {
borderWidth: 0,
fontFamily: "SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace",
padding: 0,
"&:last-child": {
paddingRight: 0
}
paddingRight: 0,
},
},
lineNumber: {
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
// interact with user selections or searching.
"&::before": {
content: "attr(data-line-number)"
}
content: "attr(data-line-number)",
},
},
line: {
textAlign: "left",
whiteSpace: "pre-wrap"
}
whiteSpace: "pre-wrap",
},
});
interface Props {
type Props = {
lines: string[];
}
};
class NumberedLines extends React.Component<Props & WithStyles<typeof styles>> {
render() {

View file

@ -1,6 +1,4 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import { createStyles, Theme, withStyles, WithStyles } from "@material-ui/core";
import React, { HTMLAttributes } from "react";
const styles = (theme: Theme) =>
@ -9,9 +7,9 @@ const styles = (theme: Theme) =>
color: theme.palette.primary.main,
"&:hover": {
cursor: "pointer",
textDecoration: "underline"
}
}
textDecoration: "underline",
},
},
});
class SpanButton extends React.Component<

View file

@ -1,16 +1,14 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import { createStyles, Theme, withStyles, WithStyles } from "@material-ui/core";
import React from "react";
const blend = (
[r1, g1, b1]: number[],
[r2, g2, b2]: number[],
ratio: number
ratio: number,
) => [
r1 * (1 - ratio) + r2 * ratio,
g1 * (1 - ratio) + g2 * ratio,
b1 * (1 - ratio) + b2 * ratio
b1 * (1 - ratio) + b2 * ratio,
];
const styles = (theme: Theme) =>
@ -18,18 +16,18 @@ const styles = (theme: Theme) =>
root: {
borderColor: theme.palette.divider,
borderStyle: "solid",
borderWidth: 1
borderWidth: 1,
},
inner: {
paddingLeft: theme.spacing(1),
paddingRight: theme.spacing(1)
}
paddingRight: theme.spacing(1),
},
});
interface Props {
type Props = {
percent: number;
text: string;
}
};
class UsageBar extends React.Component<Props & WithStyles<typeof styles>> {
render() {

View file

@ -1,6 +1,6 @@
export const formatByteAmount = (
amount: number,
unit: "mebibyte" | "gibibyte"
unit: "mebibyte" | "gibibyte",
) =>
`${(
amount / (unit === "mebibyte" ? Math.pow(1024, 2) : Math.pow(1024, 3))
@ -9,7 +9,7 @@ export const formatByteAmount = (
export const formatUsage = (
used: number,
total: number,
unit: "mebibyte" | "gibibyte"
unit: "mebibyte" | "gibibyte",
) => {
const usedFormatted = formatByteAmount(used, unit);
const totalFormatted = formatByteAmount(total, unit);
@ -27,6 +27,6 @@ export const formatDuration = (durationInSeconds: number) => {
durationDays ? `${durationDays}d` : "",
`${pad(durationHours)}h`,
`${pad(durationMinutes)}m`,
`${pad(durationSeconds)}s`
`${pad(durationSeconds)}s`,
].join(" ");
};

View file

@ -1,9 +1,12 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import Tab from "@material-ui/core/Tab";
import Tabs from "@material-ui/core/Tabs";
import Typography from "@material-ui/core/Typography";
import {
createStyles,
Tab,
Tabs,
Theme,
Typography,
WithStyles,
withStyles,
} from "@material-ui/core";
import React from "react";
import { connect } from "react-redux";
import { getNodeInfo, getRayletInfo, getTuneAvailability } from "../../api";
@ -21,19 +24,19 @@ const styles = (theme: Theme) =>
backgroundColor: theme.palette.background.paper,
padding: theme.spacing(2),
"& > :not(:first-child)": {
marginTop: theme.spacing(4)
}
marginTop: theme.spacing(4),
},
},
tabs: {
borderBottomColor: theme.palette.divider,
borderBottomStyle: "solid",
borderBottomWidth: 1
}
borderBottomWidth: 1,
},
});
const mapStateToProps = (state: StoreState) => ({
tab: state.dashboard.tab,
tuneAvailability: state.dashboard.tuneAvailability
tuneAvailability: state.dashboard.tuneAvailability,
});
const mapDispatchToProps = dashboardActions;
@ -50,7 +53,7 @@ class Dashboard extends React.Component<
const [nodeInfo, rayletInfo, tuneAvailability] = await Promise.all([
getNodeInfo(),
getRayletInfo(),
getTuneAvailability()
getTuneAvailability(),
]);
this.props.setNodeAndRayletInfo({ nodeInfo, rayletInfo });
this.props.setTuneAvailability({ tuneAvailability });
@ -80,7 +83,7 @@ class Dashboard extends React.Component<
{ label: "Machine view", component: NodeInfo },
{ label: "Logical view", component: LogicalView },
{ 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
@ -112,5 +115,5 @@ class Dashboard extends React.Component<
export default connect(
mapStateToProps,
mapDispatchToProps
mapDispatchToProps,
)(withStyles(styles)(Dashboard));

View file

@ -1,7 +1,10 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import Typography from "@material-ui/core/Typography";
import {
createStyles,
Theme,
Typography,
WithStyles,
withStyles,
} from "@material-ui/core";
import React from "react";
import { connect } from "react-redux";
import { StoreState } from "../../store";
@ -9,23 +12,23 @@ import { StoreState } from "../../store";
const styles = (theme: Theme) =>
createStyles({
root: {
marginTop: theme.spacing(2)
marginTop: theme.spacing(2),
},
lastUpdated: {
color: theme.palette.text.secondary,
fontSize: "0.8125rem",
textAlign: "center"
textAlign: "center",
},
error: {
color: theme.palette.error.main,
fontSize: "0.8125rem",
textAlign: "center"
}
textAlign: "center",
},
});
const mapStateToProps = (state: StoreState) => ({
lastUpdatedAt: state.dashboard.lastUpdatedAt,
error: state.dashboard.error
error: state.dashboard.error,
});
class LastUpdated extends React.Component<

View file

@ -1,9 +1,11 @@
import Collapse from "@material-ui/core/Collapse";
import orange from "@material-ui/core/colors/orange";
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import Typography from "@material-ui/core/Typography";
import {
Collapse,
createStyles,
Theme,
Typography,
withStyles,
WithStyles,
} from "@material-ui/core";
import React from "react";
import {
checkProfilingStatus,
@ -11,7 +13,7 @@ import {
getProfilingResultURL,
launchKillActor,
launchProfiling,
RayletInfoResponse
RayletInfoResponse,
} from "../../../api";
import Actors from "./Actors";
@ -22,47 +24,47 @@ const styles = (theme: Theme) =>
borderStyle: "solid",
borderWidth: 1,
marginTop: theme.spacing(2),
padding: theme.spacing(2)
padding: theme.spacing(2),
},
title: {
color: theme.palette.text.secondary,
fontSize: "0.75rem"
fontSize: "0.75rem",
},
action: {
color: theme.palette.primary.main,
textDecoration: "none",
"&:hover": {
cursor: "pointer"
}
cursor: "pointer",
},
},
invalidStateTypeInfeasible: {
color: theme.palette.error.main
color: theme.palette.error.main,
},
invalidStateTypePendingActor: {
color: orange[500]
color: theme.palette.secondary.main,
},
information: {
fontSize: "0.875rem"
fontSize: "0.875rem",
},
datum: {
"&:not(:first-child)": {
marginLeft: theme.spacing(2)
}
marginLeft: theme.spacing(2),
},
},
webuiDisplay: {
fontSize: "0.875rem"
fontSize: "0.875rem",
},
inlineHTML: {
fontSize: "0.875rem",
display: "inline"
}
display: "inline",
},
});
interface Props {
type Props = {
actor: RayletInfoResponse["actors"][keyof RayletInfoResponse["actors"]];
}
};
interface State {
type State = {
expanded: boolean;
profiling: {
[profilingId: string]: {
@ -70,12 +72,12 @@ interface State {
latestResponse: CheckProfilingStatusResponse | null;
};
};
}
};
class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
state: State = {
expanded: true,
profiling: {}
profiling: {},
};
setExpanded = (expanded: boolean) => () => {
@ -88,24 +90,24 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
const profilingId = await launchProfiling(
actor.nodeId,
actor.pid,
duration
duration,
);
this.setState(state => ({
this.setState((state) => ({
profiling: {
...state.profiling,
[profilingId]: { startTime: Date.now(), latestResponse: null }
}
[profilingId]: { startTime: Date.now(), latestResponse: null },
},
}));
const checkProfilingStatusLoop = async () => {
const response = await checkProfilingStatus(profilingId);
this.setState(state => ({
this.setState((state) => ({
profiling: {
...state.profiling,
[profilingId]: {
...state.profiling[profilingId],
latestResponse: response
}
}
latestResponse: response,
},
},
}));
if (response.status === "pending") {
setTimeout(checkProfilingStatusLoop, 1000);
@ -131,11 +133,11 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
? [
{
label: "ActorTitle",
value: actor.actorTitle
value: actor.actorTitle,
},
{
label: "State",
value: actor.state.toLocaleString()
value: actor.state.toLocaleString(),
},
{
label: "Resources",
@ -144,28 +146,28 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
Object.entries(actor.usedResources)
.sort((a, b) => a[0].localeCompare(b[0]))
.map(([key, value]) => `${value.toLocaleString()} ${key}`)
.join(", ")
.join(", "),
},
{
label: "Pending",
value: actor.taskQueueLength.toLocaleString()
value: actor.taskQueueLength.toLocaleString(),
},
{
label: "Executed",
value: actor.numExecutedTasks.toLocaleString()
value: actor.numExecutedTasks.toLocaleString(),
},
{
label: "NumObjectIdsInScope",
value: actor.numObjectIdsInScope.toLocaleString()
value: actor.numObjectIdsInScope.toLocaleString(),
},
{
label: "NumLocalObjects",
value: actor.numLocalObjects.toLocaleString()
value: actor.numLocalObjects.toLocaleString(),
},
{
label: "UsedLocalObjectMemory",
value: actor.usedObjectStoreMemory.toLocaleString()
}
value: actor.usedObjectStoreMemory.toLocaleString(),
},
// {
// label: "Task",
// value: actor.currentTaskFuncDesc.join(".")
@ -174,7 +176,7 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
: [
{
label: "ID",
value: actor.actorId
value: actor.actorId,
},
{
label: "Required resources",
@ -183,8 +185,8 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
Object.entries(actor.requiredResources)
.sort((a, b) => a[0].localeCompare(b[0]))
.map(([key, value]) => `${value.toLocaleString()} ${key}`)
.join(", ")
}
.join(", "),
},
];
// Construct the custom message from the actor.
@ -242,7 +244,7 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
</React.Fragment>
)}{" "}
(Profile for
{[10, 30, 60].map(duration => (
{[10, 30, 60].map((duration) => (
<React.Fragment>
{" "}
<span
@ -268,7 +270,7 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
(
{latestResponse.status === "pending" ? (
`Profiling for ${Math.round(
(Date.now() - startTime) / 1000
(Date.now() - startTime) / 1000,
)}s...`
) : latestResponse.status === "finished" ? (
<a
@ -281,12 +283,10 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
</a>
) : latestResponse.status === "error" ? (
`Profiling error: ${latestResponse.error.trim()}`
) : (
undefined
)}
) : undefined}
){" "}
</React.Fragment>
)
),
)}
</React.Fragment>
) : actor.invalidStateType === "infeasibleActor" ? (
@ -310,7 +310,7 @@ class Actor extends React.Component<Props & WithStyles<typeof styles>, State> {
{label}: {value}
</span>{" "}
</React.Fragment>
)
),
)}
</Typography>
{actor.state !== -1 && (

View file

@ -1,15 +1,13 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import { createStyles, Theme, withStyles, WithStyles } from "@material-ui/core";
import React from "react";
import { RayletInfoResponse } from "../../../api";
import Actor from "./Actor";
const styles = (theme: Theme) => createStyles({});
interface Props {
type Props = {
actors: RayletInfoResponse["actors"];
}
};
class Actors extends React.Component<Props & WithStyles<typeof styles>> {
render() {

View file

@ -1,7 +1,10 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import Typography from "@material-ui/core/Typography";
import {
createStyles,
Theme,
Typography,
WithStyles,
withStyles,
} from "@material-ui/core";
import WarningRoundedIcon from "@material-ui/icons/WarningRounded";
import React from "react";
import { connect } from "react-redux";
@ -12,16 +15,16 @@ const styles = (theme: Theme) =>
createStyles({
warning: {
fontSize: "0.8125rem",
marginBottom: theme.spacing(2)
marginBottom: theme.spacing(2),
},
warningIcon: {
fontSize: "1.25em",
verticalAlign: "text-bottom"
}
verticalAlign: "text-bottom",
},
});
const mapStateToProps = (state: StoreState) => ({
rayletInfo: state.dashboard.rayletInfo
rayletInfo: state.dashboard.rayletInfo,
});
class LogicalView extends React.Component<

View file

@ -1,12 +1,15 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
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 Typography from "@material-ui/core/Typography";
import {
createStyles,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
Theme,
Typography,
withStyles,
WithStyles,
} from "@material-ui/core";
import React from "react";
import { connect } from "react-redux";
import { StoreState } from "../../../store";
@ -18,33 +21,33 @@ import TotalRow from "./TotalRow";
const styles = (theme: Theme) =>
createStyles({
table: {
marginTop: theme.spacing(1)
marginTop: theme.spacing(1),
},
cell: {
padding: theme.spacing(1),
textAlign: "center",
"&:last-child": {
paddingRight: theme.spacing(1)
}
}
paddingRight: theme.spacing(1),
},
},
});
const mapStateToProps = (state: StoreState) => ({
nodeInfo: state.dashboard.nodeInfo,
rayletInfo: state.dashboard.rayletInfo
rayletInfo: state.dashboard.rayletInfo,
});
interface State {
type State = {
logDialog: { hostname: string; pid: number | null } | null;
errorDialog: { hostname: string; pid: number | null } | null;
}
};
class NodeInfo extends React.Component<
WithStyles<typeof styles> & ReturnType<typeof mapStateToProps>
> {
state: State = {
logDialog: null,
errorDialog: null
errorDialog: null,
};
setLogDialog = (hostname: string, pid: number | null) => {
@ -135,7 +138,7 @@ class NodeInfo extends React.Component<
</TableRow>
</TableHead>
<TableBody>
{nodeInfo.clients.map(client => (
{nodeInfo.clients.map((client) => (
<NodeRowGroup
key={client.ip}
node={client}

View file

@ -1,8 +1,11 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import TableCell from "@material-ui/core/TableCell";
import TableRow from "@material-ui/core/TableRow";
import {
createStyles,
TableCell,
TableRow,
Theme,
withStyles,
WithStyles,
} from "@material-ui/core";
import AddIcon from "@material-ui/icons/Add";
import RemoveIcon from "@material-ui/icons/Remove";
import classNames from "classnames";
@ -25,27 +28,27 @@ const styles = (theme: Theme) =>
padding: theme.spacing(1),
textAlign: "center",
"&:last-child": {
paddingRight: theme.spacing(1)
}
paddingRight: theme.spacing(1),
},
},
expandCollapseCell: {
cursor: "pointer"
cursor: "pointer",
},
expandCollapseIcon: {
color: theme.palette.text.secondary,
fontSize: "1.5em",
verticalAlign: "middle"
verticalAlign: "middle",
},
extraInfo: {
fontFamily: "SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace",
whiteSpace: "pre"
}
whiteSpace: "pre",
},
});
type ArrayType<T> = T extends Array<infer U> ? U : never;
type Node = ArrayType<NodeInfoResponse["clients"]>;
interface Props {
type Props = {
node: Node;
raylet: RayletInfoResponse["nodes"][keyof RayletInfoResponse["nodes"]] | null;
logCounts: {
@ -59,23 +62,23 @@ interface Props {
setLogDialog: (hostname: string, pid: number | null) => void;
setErrorDialog: (hostname: string, pid: number | null) => void;
initialExpanded: boolean;
}
};
interface State {
type State = {
expanded: boolean;
}
};
class NodeRowGroup extends React.Component<
Props & WithStyles<typeof styles>,
State
> {
state: State = {
expanded: this.props.initialExpanded
expanded: this.props.initialExpanded,
};
toggleExpand = () => {
this.setState(state => ({
expanded: !state.expanded
this.setState((state) => ({
expanded: !state.expanded,
}));
};
@ -87,7 +90,7 @@ class NodeRowGroup extends React.Component<
logCounts,
errorCounts,
setLogDialog,
setErrorDialog
setErrorDialog,
} = this.props;
const { expanded } = this.state;
@ -102,12 +105,12 @@ class NodeRowGroup extends React.Component<
{ NodeFeature: NodeReceived, WorkerFeature: WorkerReceived },
{
NodeFeature: makeNodeLogs(logCounts, setLogDialog),
WorkerFeature: makeWorkerLogs(logCounts, setLogDialog)
WorkerFeature: makeWorkerLogs(logCounts, setLogDialog),
},
{
NodeFeature: makeNodeErrors(errorCounts, setErrorDialog),
WorkerFeature: makeWorkerErrors(errorCounts, setErrorDialog)
}
WorkerFeature: makeWorkerErrors(errorCounts, setErrorDialog),
},
];
return (

View file

@ -1,8 +1,11 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import TableCell from "@material-ui/core/TableCell";
import TableRow from "@material-ui/core/TableRow";
import {
createStyles,
TableCell,
TableRow,
Theme,
WithStyles,
withStyles,
} from "@material-ui/core";
import LayersIcon from "@material-ui/icons/Layers";
import React from "react";
import { NodeInfoResponse } from "../../../api";
@ -26,17 +29,17 @@ const styles = (theme: Theme) =>
padding: theme.spacing(1),
textAlign: "center",
"&:last-child": {
paddingRight: theme.spacing(1)
}
paddingRight: theme.spacing(1),
},
},
totalIcon: {
color: theme.palette.text.secondary,
fontSize: "1.5em",
verticalAlign: "middle"
}
verticalAlign: "middle",
},
});
interface Props {
type Props = {
nodes: NodeInfoResponse["clients"];
logCounts: {
[ip: string]: {
@ -50,7 +53,7 @@ interface Props {
total: number;
};
};
}
};
class TotalRow extends React.Component<Props & WithStyles<typeof styles>> {
render() {
@ -66,7 +69,7 @@ class TotalRow extends React.Component<Props & WithStyles<typeof styles>> {
{ ClusterFeature: ClusterSent },
{ ClusterFeature: ClusterReceived },
{ ClusterFeature: makeClusterLogs(logCounts) },
{ ClusterFeature: makeClusterErrors(errorCounts) }
{ ClusterFeature: makeClusterErrors(errorCounts) },
];
return (

View file

@ -1,8 +1,11 @@
import { fade } from "@material-ui/core/styles/colorManipulator";
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import Typography from "@material-ui/core/Typography";
import {
createStyles,
fade,
Theme,
Typography,
withStyles,
WithStyles,
} from "@material-ui/core";
import React from "react";
import { ErrorsResponse, getErrors } from "../../../../../api";
import DialogWithTitle from "../../../../../common/DialogWithTitle";
@ -13,7 +16,7 @@ const styles = (theme: Theme) =>
header: {
lineHeight: 1,
marginBottom: theme.spacing(3),
marginTop: theme.spacing(3)
marginTop: theme.spacing(3),
},
error: {
backgroundColor: fade(theme.palette.error.main, 0.04),
@ -21,29 +24,29 @@ const styles = (theme: Theme) =>
borderLeftStyle: "solid",
borderLeftWidth: 2,
marginTop: theme.spacing(3),
padding: theme.spacing(2)
padding: theme.spacing(2),
},
timestamp: {
color: theme.palette.text.secondary,
marginBottom: theme.spacing(1)
}
marginBottom: theme.spacing(1),
},
});
interface Props {
type Props = {
clearErrorDialog: () => void;
hostname: string;
pid: number | null;
}
};
interface State {
type State = {
result: ErrorsResponse | null;
error: string | null;
}
};
class Errors extends React.Component<Props & WithStyles<typeof styles>, State> {
state: State = {
result: null,
error: null
error: null,
};
async componentDidMount() {

View file

@ -1,8 +1,11 @@
import { fade } from "@material-ui/core/styles/colorManipulator";
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import Typography from "@material-ui/core/Typography";
import {
createStyles,
fade,
Theme,
Typography,
WithStyles,
withStyles,
} from "@material-ui/core";
import React from "react";
import { getLogs, LogsResponse } from "../../../../../api";
import DialogWithTitle from "../../../../../common/DialogWithTitle";
@ -13,32 +16,32 @@ const styles = (theme: Theme) =>
header: {
lineHeight: 1,
marginBottom: theme.spacing(3),
marginTop: theme.spacing(3)
marginTop: theme.spacing(3),
},
log: {
backgroundColor: fade(theme.palette.primary.main, 0.04),
borderLeftColor: theme.palette.primary.main,
borderLeftStyle: "solid",
borderLeftWidth: 2,
padding: theme.spacing(2)
}
padding: theme.spacing(2),
},
});
interface Props {
type Props = {
clearLogDialog: () => void;
hostname: string;
pid: number | null;
}
};
interface State {
type State = {
result: LogsResponse | null;
error: string | null;
}
};
class Logs extends React.Component<Props & WithStyles<typeof styles>, State> {
state: State = {
result: null,
error: null
error: null,
};
async componentDidMount() {

View file

@ -3,14 +3,14 @@ import UsageBar from "../../../../common/UsageBar";
import {
ClusterFeatureComponent,
NodeFeatureComponent,
WorkerFeatureComponent
WorkerFeatureComponent,
} from "./types";
const getWeightedAverage = (
input: {
weight: number;
value: number;
}[]
}[],
) => {
if (input.length === 0) {
return 0;
@ -27,7 +27,7 @@ const getWeightedAverage = (
export const ClusterCPU: ClusterFeatureComponent = ({ nodes }) => {
const cpuWeightedAverage = getWeightedAverage(
nodes.map(node => ({ weight: node.cpus[0], value: node.cpu }))
nodes.map((node) => ({ weight: node.cpus[0], value: node.cpu })),
);
return (
<div style={{ minWidth: 60 }}>

View file

@ -1,11 +1,11 @@
import Typography from "@material-ui/core/Typography";
import { Typography } from "@material-ui/core";
import React from "react";
import { formatUsage } from "../../../../common/formatUtils";
import UsageBar from "../../../../common/UsageBar";
import {
ClusterFeatureComponent,
NodeFeatureComponent,
WorkerFeatureComponent
WorkerFeatureComponent,
} from "./types";
export const ClusterDisk: ClusterFeatureComponent = ({ nodes }) => {

View file

@ -1,10 +1,10 @@
import Typography from "@material-ui/core/Typography";
import { Typography } from "@material-ui/core";
import React from "react";
import SpanButton from "../../../../common/SpanButton";
import {
ClusterFeatureComponent,
NodeFeatureComponent,
WorkerFeatureComponent
WorkerFeatureComponent,
} from "./types";
export const makeClusterErrors = (errorCounts: {
@ -38,7 +38,7 @@ export const makeNodeErrors = (
perWorker: { [pid: string]: number };
total: number;
},
setErrorDialog: (hostname: string, pid: number | null) => void
setErrorDialog: (hostname: string, pid: number | null) => void,
): NodeFeatureComponent => ({ node }) =>
errorCounts.total === 0 ? (
<Typography color="textSecondary" component="span" variant="inherit">
@ -55,7 +55,7 @@ export const makeWorkerErrors = (
perWorker: { [pid: string]: number };
total: number;
},
setErrorDialog: (hostname: string, pid: number | null) => void
setErrorDialog: (hostname: string, pid: number | null) => void,
): WorkerFeatureComponent => ({ node, worker }) =>
errorCounts.perWorker[worker.pid] === 0 ? (
<Typography color="textSecondary" component="span" variant="inherit">

View file

@ -2,7 +2,7 @@ import React from "react";
import {
ClusterFeatureComponent,
NodeFeatureComponent,
WorkerFeatureComponent
WorkerFeatureComponent,
} from "./types";
export const ClusterHost: ClusterFeatureComponent = ({ nodes }) => (

View file

@ -1,10 +1,10 @@
import Typography from "@material-ui/core/Typography";
import { Typography } from "@material-ui/core";
import React from "react";
import SpanButton from "../../../../common/SpanButton";
import {
ClusterFeatureComponent,
NodeFeatureComponent,
WorkerFeatureComponent
WorkerFeatureComponent,
} from "./types";
export const makeClusterLogs = (logCounts: {
@ -37,7 +37,7 @@ export const makeNodeLogs = (
perWorker: { [pid: string]: number };
total: number;
},
setLogDialog: (hostname: string, pid: number | null) => void
setLogDialog: (hostname: string, pid: number | null) => void,
): NodeFeatureComponent => ({ node }) =>
logCounts.total === 0 ? (
<Typography color="textSecondary" component="span" variant="inherit">
@ -55,7 +55,7 @@ export const makeWorkerLogs = (
perWorker: { [pid: string]: number };
total: number;
},
setLogDialog: (hostname: string, pid: number | null) => void
setLogDialog: (hostname: string, pid: number | null) => void,
): WorkerFeatureComponent => ({ node, worker }) =>
logCounts.perWorker[worker.pid] === 0 ? (
<Typography color="textSecondary" component="span" variant="inherit">

View file

@ -4,7 +4,7 @@ import UsageBar from "../../../../common/UsageBar";
import {
ClusterFeatureComponent,
NodeFeatureComponent,
WorkerFeatureComponent
WorkerFeatureComponent,
} from "./types";
export const ClusterRAM: ClusterFeatureComponent = ({ nodes }) => {

View file

@ -1,10 +1,10 @@
import Typography from "@material-ui/core/Typography";
import { Typography } from "@material-ui/core";
import React from "react";
import { formatByteAmount } from "../../../../common/formatUtils";
import {
ClusterFeatureComponent,
NodeFeatureComponent,
WorkerFeatureComponent
WorkerFeatureComponent,
} from "./types";
export const ClusterReceived: ClusterFeatureComponent = ({ nodes }) => {

View file

@ -1,10 +1,10 @@
import Typography from "@material-ui/core/Typography";
import { Typography } from "@material-ui/core";
import React from "react";
import { formatByteAmount } from "../../../../common/formatUtils";
import {
ClusterFeatureComponent,
NodeFeatureComponent,
WorkerFeatureComponent
WorkerFeatureComponent,
} from "./types";
export const ClusterSent: ClusterFeatureComponent = ({ nodes }) => {

View file

@ -1,10 +1,10 @@
import Typography from "@material-ui/core/Typography";
import { Typography } from "@material-ui/core";
import React from "react";
import { formatDuration } from "../../../../common/formatUtils";
import {
ClusterFeatureComponent,
NodeFeatureComponent,
WorkerFeatureComponent
WorkerFeatureComponent,
} from "./types";
const getUptime = (bootTime: number) => Date.now() / 1000 - bootTime;

View file

@ -2,7 +2,7 @@ import React from "react";
import {
ClusterFeatureComponent,
NodeFeatureComponent,
WorkerFeatureComponent
WorkerFeatureComponent,
} from "./types";
export const ClusterWorkers: ClusterFeatureComponent = ({ nodes }) => {

View file

@ -10,11 +10,11 @@ type NodeFeatureData = { node: Node };
type WorkerFeatureData = { node: Node; worker: Worker };
export type ClusterFeatureComponent = (
data: ClusterFeatureData
data: ClusterFeatureData,
) => React.ReactElement;
export type NodeFeatureComponent = (
data: NodeFeatureData
data: NodeFeatureData,
) => React.ReactElement;
export type WorkerFeatureComponent = (
data: WorkerFeatureData
data: WorkerFeatureData,
) => React.ReactElement;

View file

@ -1,12 +1,15 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
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 Typography from "@material-ui/core/Typography";
import {
createStyles,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
Theme,
Typography,
withStyles,
WithStyles,
} from "@material-ui/core";
import classNames from "classnames";
import React from "react";
import { connect } from "react-redux";
@ -18,7 +21,7 @@ const styles = (theme: Theme) =>
createStyles({
table: {
marginTop: theme.spacing(1),
width: "auto"
width: "auto",
},
cell: {
paddingTop: theme.spacing(1),
@ -27,16 +30,16 @@ const styles = (theme: Theme) =>
paddingRight: theme.spacing(3),
textAlign: "center",
"&:last-child": {
paddingRight: theme.spacing(3)
}
paddingRight: theme.spacing(3),
},
},
key: {
color: theme.palette.text.secondary
}
color: theme.palette.text.secondary,
},
});
const mapStateToProps = (state: StoreState) => ({
rayConfig: state.dashboard.rayConfig
rayConfig: state.dashboard.rayConfig,
});
const mapDispatchToProps = dashboardActions;
@ -74,34 +77,34 @@ class RayConfig extends React.Component<
const formattedRayConfig = [
{
key: "Autoscaling mode",
value: rayConfig.autoscaling_mode
value: rayConfig.autoscaling_mode,
},
{
key: "Head node type",
value: rayConfig.head_type
value: rayConfig.head_type,
},
{
key: "Worker node type",
value: rayConfig.worker_type
value: rayConfig.worker_type,
},
{
key: "Min worker nodes",
value: rayConfig.min_workers
value: rayConfig.min_workers,
},
{
key: "Initial worker nodes",
value: rayConfig.initial_workers
value: rayConfig.initial_workers,
},
{
key: "Max worker nodes",
value: rayConfig.max_workers
value: rayConfig.max_workers,
},
{
key: "Idle timeout",
value: `${rayConfig.idle_timeout_minutes} ${
rayConfig.idle_timeout_minutes === 1 ? "minute" : "minutes"
}`
}
}`,
},
];
return (
@ -132,5 +135,5 @@ class RayConfig extends React.Component<
export default connect(
mapStateToProps,
mapDispatchToProps
mapDispatchToProps,
)(withStyles(styles)(RayConfig));

View file

@ -3,13 +3,13 @@ import {
NodeInfoResponse,
RayConfigResponse,
RayletInfoResponse,
TuneAvailabilityResponse,
TuneJobResponse,
TuneAvailabilityResponse
} from "../../api";
const name = "dashboard";
interface State {
type State = {
tab: number;
rayConfig: RayConfigResponse | null;
nodeInfo: NodeInfoResponse | null;
@ -18,7 +18,7 @@ interface State {
tuneAvailability: boolean;
lastUpdatedAt: number | null;
error: string | null;
}
};
const initialState: State = {
tab: 0,
@ -28,7 +28,7 @@ const initialState: State = {
tuneInfo: null,
tuneAvailability: false,
lastUpdatedAt: null,
error: null
error: null,
};
const slice = createSlice({
@ -46,7 +46,7 @@ const slice = createSlice({
action: PayloadAction<{
nodeInfo: NodeInfoResponse;
rayletInfo: RayletInfoResponse;
}>
}>,
) => {
state.nodeInfo = action.payload.nodeInfo;
state.rayletInfo = action.payload.rayletInfo;
@ -60,7 +60,7 @@ const slice = createSlice({
state,
action: PayloadAction<{
tuneAvailability: TuneAvailabilityResponse;
}>
}>,
) => {
const tuneAvailability =
action.payload.tuneAvailability === null
@ -71,8 +71,8 @@ const slice = createSlice({
},
setError: (state, action: PayloadAction<string | null>) => {
state.error = action.payload;
}
}
},
},
});
export const dashboardActions = slice.actions;

View file

@ -1,46 +1,49 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import {
createStyles,
Tab,
Tabs,
Theme,
Typography,
WithStyles,
withStyles,
} from "@material-ui/core";
import WarningRoundedIcon from "@material-ui/icons/WarningRounded";
import React from "react";
import { connect } from "react-redux";
import { getTuneInfo } from "../../../api";
import { StoreState } from "../../../store";
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 TuneTensorBoard from "./TuneTensorBoard";
const styles = (theme: Theme) =>
createStyles({
root: {
backgroundColor: theme.palette.background.paper
backgroundColor: theme.palette.background.paper,
},
tabs: {
borderBottomColor: theme.palette.divider,
borderBottomStyle: "solid",
borderBottomWidth: 1
borderBottomWidth: 1,
},
warning: {
fontSize: "0.8125rem"
fontSize: "0.8125rem",
},
warningIcon: {
fontSize: "1.25em",
verticalAlign: "text-bottom"
}
verticalAlign: "text-bottom",
},
});
const mapStateToProps = (state: StoreState) => ({
tuneInfo: state.dashboard.tuneInfo
tuneInfo: state.dashboard.tuneInfo,
});
const mapDispatchToProps = dashboardActions;
interface State {
type State = {
tabIndex: number;
}
};
class Tune extends React.Component<
WithStyles<typeof styles> &
@ -51,7 +54,7 @@ class Tune extends React.Component<
timeout: number = 0;
state: State = {
tabIndex: 0
tabIndex: 0,
};
refreshTuneInfo = async () => {
@ -75,7 +78,7 @@ class Tune extends React.Component<
handleTabChange = (event: React.ChangeEvent<{}>, value: number) => {
this.setState({
tabIndex: value
tabIndex: value,
});
};
@ -86,7 +89,7 @@ class Tune extends React.Component<
const tabs = [
{ label: "Table", component: TuneTable },
{ label: "TensorBoard", component: TuneTensorBoard }
{ label: "TensorBoard", component: TuneTensorBoard },
];
const SelectedComponent = tabs[tabIndex].component;
@ -115,5 +118,5 @@ class Tune extends React.Component<
export default connect(
mapStateToProps,
mapDispatchToProps
mapDispatchToProps,
)(withStyles(styles)(Tune));

View file

@ -1,47 +1,50 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import {
createStyles,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
TableSortLabel,
Theme,
withStyles,
WithStyles,
} from "@material-ui/core";
import React from "react";
import { connect } from "react-redux";
import { TuneTrial } from "../../../api";
import { StoreState } from "../../../store";
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) =>
createStyles({
root: {
padding: theme.spacing(2),
"& > :not(:first-child)": {
marginTop: theme.spacing(2)
}
marginTop: theme.spacing(2),
},
},
table: {
marginTop: theme.spacing(1)
marginTop: theme.spacing(1),
},
cell: {
padding: theme.spacing(1),
textAlign: "right",
"&:last-child": {
paddingRight: theme.spacing(1)
}
}
paddingRight: theme.spacing(1),
},
},
});
const mapStateToProps = (state: StoreState) => ({
tuneInfo: state.dashboard.tuneInfo
tuneInfo: state.dashboard.tuneInfo,
});
interface State {
type State = {
metricParamColumn: string;
ascending: boolean;
sortedColumn: keyof TuneTrial | undefined;
}
};
const mapDispatchToProps = dashboardActions;
@ -56,7 +59,7 @@ class TuneTable extends React.Component<
state: State = {
sortedColumn: undefined,
ascending: true,
metricParamColumn: ""
metricParamColumn: "",
};
onColumnClick = (column: keyof TuneTrial, metricParamColumn?: string) => {
@ -68,12 +71,12 @@ class TuneTable extends React.Component<
}
this.setState({
sortedColumn: column,
ascending: ascending
ascending: ascending,
});
if (metricParamColumn) {
this.setState({
metricParamColumn: metricParamColumn
metricParamColumn: metricParamColumn,
});
}
};
@ -82,14 +85,11 @@ class TuneTable extends React.Component<
* Replaces all underscores with spaces and capitalizes all words
* in str
*/
humanize = (str: string) => {
var i,
frags = str.split("_");
for (i = 0; i < frags.length; i++) {
frags[i] = frags[i].charAt(0).toUpperCase() + frags[i].slice(1);
}
return frags.join(" ");
};
humanize = (str: string) =>
str
.split("_")
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
.join(" ");
sortedCell = (name: keyof TuneTrial, chosenMetricParam?: string) => {
const { tuneInfo, classes } = this.props;
@ -154,11 +154,11 @@ class TuneTable extends React.Component<
if (sortedColumn) {
if (ascending) {
trialDetails.sort((a, b) =>
getAttribute(a) > getAttribute(b) ? 1 : -1
getAttribute(a) > getAttribute(b) ? 1 : -1,
);
} else if (!ascending) {
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 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(
tuneInfo["trial_records"][firstTrial]["metrics"]
tuneInfo["trial_records"][firstTrial]["metrics"],
);
const trialDetails = this.sortedTrialRecords();
@ -194,9 +194,9 @@ class TuneTable extends React.Component<
{this.sortedCell("trial_id")}
{this.sortedCell("job_id")}
{this.sortedCell("start_time")}
{paramNames.map(value => this.sortedCell("params", value))}
{paramNames.map((value) => this.sortedCell("params", value))}
{this.sortedCell("status")}
{metricNames.map(value => this.sortedCell("metrics", value))}
{metricNames.map((value) => this.sortedCell("metrics", value))}
</TableRow>
</TableHead>
<TableBody>
@ -212,7 +212,7 @@ class TuneTable extends React.Component<
<TableCell className={classes.cell}>
{trial["start_time"]}
</TableCell>
{paramNames.map(value => (
{paramNames.map((value) => (
<TableCell className={classes.cell} key={value}>
{trial["params"][value]}
</TableCell>
@ -221,7 +221,7 @@ class TuneTable extends React.Component<
{trial["status"]}
</TableCell>
{trial["metrics"] &&
metricNames.map(value => (
metricNames.map((value) => (
<TableCell className={classes.cell} key={value}>
{trial["metrics"][value]}
</TableCell>
@ -237,5 +237,5 @@ class TuneTable extends React.Component<
export default connect(
mapStateToProps,
mapDispatchToProps
mapDispatchToProps,
)(withStyles(styles)(TuneTable));

View file

@ -1,11 +1,14 @@
import { Theme } from "@material-ui/core/styles/createMuiTheme";
import createStyles from "@material-ui/core/styles/createStyles";
import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles";
import {
createStyles,
Theme,
Typography,
WithStyles,
withStyles,
} from "@material-ui/core";
import React from "react";
import { connect } from "react-redux";
import { StoreState } from "../../../store";
import { dashboardActions } from "../state";
import React from "react";
import Typography from "@material-ui/core/Typography";
const styles = (theme: Theme) =>
createStyles({
@ -13,21 +16,21 @@ const styles = (theme: Theme) =>
backgroundColor: theme.palette.background.paper,
padding: theme.spacing(2),
"& > :not(:first-child)": {
marginTop: theme.spacing(4)
}
marginTop: theme.spacing(4),
},
},
board: {
width: "100%",
height: "1000px",
border: "none"
border: "none",
},
warning: {
fontSize: "0.8125rem"
}
fontSize: "0.8125rem",
},
});
const mapStateToProps = (state: StoreState) => ({
error: state.dashboard.error
error: state.dashboard.error,
});
const mapDispatchToProps = dashboardActions;
@ -60,5 +63,5 @@ class TuneTensorBoard extends React.Component<
export default connect(
mapStateToProps,
mapDispatchToProps
mapDispatchToProps,
)(withStyles(styles)(TuneTensorBoard));

View file

@ -3,9 +3,9 @@ import { dashboardReducer } from "./pages/dashboard/state";
export const store = configureStore({
reducer: {
dashboard: dashboardReducer
dashboard: dashboardReducer,
},
devTools: process.env.NODE_ENV === "development"
devTools: process.env.NODE_ENV === "development",
});
export type StoreState = ReturnType<typeof store.getState>;