Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dashboard] Upgrade to MUIv5 and dependency updates #45789

Merged
merged 12 commits into from
Jul 2, 2024
27,419 changes: 8,866 additions & 18,553 deletions dashboard/client/package-lock.json

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions dashboard/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,20 @@
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.15.5",
"@mui/material": "^5.15.5",
"@mui/styles": "^5.15.5",
"@reduxjs/toolkit": "^1.3.1",
"@types/classnames": "^2.2.10",
"@types/jest": "^27.5.2",
"@types/lodash": "^4.14.161",
"@types/lowlight": "^0.0.1",
"@types/node": "13.9.5",
"@types/numeral": "^0.0.26",
"@types/react-redux": "^7.1.7",
"@types/react-window": "^1.8.2",
"axios": "^0.21.1",
"classnames": "^2.2.6",
"copy-to-clipboard": "^3.3.2",
"dayjs": "^1.9.4",
"js-yaml": "^4.1.0",
"lodash": "^4.17.20",
"lowlight": "^1.14.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"lowlight": "^2.9.0",
"react": "^18.3.0",
"react-dom": "^18.3.0",
"react-icons": "^4.7.1",
"react-router-dom": "^6.4.3",
"react-scripts": "^5.0.1",
Expand All @@ -37,11 +32,11 @@
},
"devDependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^12.1.5",
"@testing-library/react": "^14.3.0",
"@testing-library/user-event": "^14.4.3",
"@types/js-yaml": "^4.0.5",
"@types/react": "^17.0.50",
"@types/react-dom": "^17.0.17",
"@types/react": "^18.3.0",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^5.41.0",
"@typescript-eslint/parser": "^5.41.0",
"eslint-plugin-import": "^2.26.0",
Expand All @@ -53,6 +48,11 @@
"resolutions": {
"@types/react": "16.9.26"
},
"jest": {
"transformIgnorePatterns": [
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new version of lowlight has extended its syntax to TypeScript, which requires additional configuration when using Jest for testing. The official recommendation is to adapt to the following scheme:

We are currently adding configuration here, is it suitable?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find any thing online about this. What happens if you don't include this?

Copy link
Contributor Author

@liuxsh9 liuxsh9 Jul 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI will fail, the error message:

image

"/node_modules/(?!lowlight)/"
]
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
Expand Down
11 changes: 1 addition & 10 deletions dashboard/client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { CssBaseline } from "@mui/material";
import {
StyledEngineProvider,
Theme,
ThemeProvider,
} from "@mui/material/styles";
import { StyledEngineProvider, ThemeProvider } from "@mui/material/styles";
import dayjs from "dayjs";
import duration from "dayjs/plugin/duration";
import React, { Suspense, useEffect, useState } from "react";
Expand Down Expand Up @@ -57,11 +53,6 @@ import { TaskPage } from "./pages/task/TaskPage";
import { getNodeList } from "./service/node";
import { lightTheme } from "./theme";

declare module "@mui/styles/defaultTheme" {
// eslint-disable-next-line @typescript-eslint/no-empty-interface, @typescript-eslint/consistent-type-definitions
interface DefaultTheme extends Theme {}
}

dayjs.extend(duration);

// lazy loading fro prevent loading too much code at once
Expand Down
80 changes: 38 additions & 42 deletions dashboard/client/src/common/CodeDialogButton/CodeDialogButton.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,9 @@
import { Card, Link, Typography } from "@mui/material";
import createStyles from "@mui/styles/createStyles";
import makeStyles from "@mui/styles/makeStyles";
import classNames from "classnames";
import { Box, Card, Link, SxProps, Theme, Typography } from "@mui/material";
import yaml from "js-yaml";
import React, { useState } from "react";
import DialogWithTitle from "../DialogWithTitle";
import { ClassNameProps } from "../props";

const useStyles = makeStyles((theme) =>
createStyles({
configText: {
whiteSpace: "pre",
fontFamily: "SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace",
padding: theme.spacing(2),
overflow: "scroll",
maxHeight: 600,
},
}),
);

export type CodeDialogButtonProps = {
/**
* Title of the dialog box
Expand All @@ -32,6 +17,7 @@ export type CodeDialogButtonProps = {
* Code to show in the dialog. If an object is passed in, that object will be stringified to yaml.
*/
code: string | object;
sx?: SxProps<Theme>;
};

/**
Expand All @@ -42,8 +28,6 @@ export const CodeDialogButton = ({
buttonText = "View",
code,
}: CodeDialogButtonProps) => {
const classes = useStyles();

const [showConfigDialog, setShowConfigDialog] = useState(false);

const handleConfigClick = () => {
Expand All @@ -63,7 +47,16 @@ export const CodeDialogButton = ({
}}
>
<Card variant="outlined">
<Typography className={classes.configText}>
<Typography
sx={{
whiteSpace: "pre",
fontFamily:
"SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace",
padding: 2,
overflow: "scroll",
maxHeight: 600,
}}
>
{typeof code === "string" ? code : yaml.dump(code, { indent: 2 })}
</Typography>
</Card>
Expand All @@ -73,24 +66,6 @@ export const CodeDialogButton = ({
);
};

const useCodeDialogButtonWithPreviewStyles = makeStyles((theme) =>
createStyles({
root: {
display: "flex",
flexWrap: "nowrap",
flexDirection: "row",
gap: theme.spacing(1),
},
previewText: {
display: "block",
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
flex: 1,
},
}),
);

type CodeDialogButtonWithPreviewProps = CodeDialogButtonProps & ClassNameProps;
Comment on lines -76 to -93
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this component has some missing styles after your PR:

Screenshot 2024-06-26 at 1 50 59 PM

You can repro this by going to the jobs page -> job detail -> runtime environment (view) button

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

/**
* Similar to CodeDialogButton but also shows a snippet of the expanded text next to the button.
Expand All @@ -99,10 +74,9 @@ export const CodeDialogButtonWithPreview = ({
code,
buttonText,
className,
sx,
...props
}: CodeDialogButtonWithPreviewProps) => {
const classes = useCodeDialogButtonWithPreviewStyles();

const codeText =
typeof code === "string"
? code
Expand All @@ -111,13 +85,35 @@ export const CodeDialogButtonWithPreview = ({
const buttonTextToPass = buttonText ?? "Expand";

return (
<div className={classNames(classes.root, className)}>
<span className={classes.previewText}>{codeText}</span>
<Box
className={className}
sx={[
{
display: "flex",
flexWrap: "nowrap",
flexDirection: "row",
gap: 1,
},
...(Array.isArray(sx) ? sx : [sx]),
]}
>
<Box
component="span"
sx={{
display: "block",
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
flex: 1,
}}
>
{codeText}
</Box>
<CodeDialogButton
code={codeText}
buttonText={buttonTextToPass}
{...props}
/>
</div>
</Box>
);
};
83 changes: 36 additions & 47 deletions dashboard/client/src/common/CollapsibleSection.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { Box, Typography } from "@mui/material";
import createStyles from "@mui/styles/createStyles";
import makeStyles from "@mui/styles/makeStyles";
import classNames from "classnames";
import { Box, SxProps, Theme, Typography } from "@mui/material";
import React, {
forwardRef,
PropsWithChildren,
Expand All @@ -11,25 +8,6 @@ import React, {
import { RiArrowDownSLine, RiArrowRightSLine } from "react-icons/ri";
import { ClassNameProps } from "./props";

const useStyles = makeStyles((theme) =>
createStyles({
title: {
display: "flex",
flexDirection: "row",
flexWrap: "nowrap",
alignItems: "center",
fontWeight: 500,
cursor: "pointer",
marginRight: theme.spacing(1),
},
icon: {
marginRight: theme.spacing(1),
width: 24,
height: 24,
},
}),
);

type CollapsibleSectionProps = PropsWithChildren<
{
/**
Expand All @@ -49,6 +27,7 @@ type CollapsibleSectionProps = PropsWithChildren<
* When enabled, we will keep the content around when collapsing but hide it via css.
*/
keepRendered?: boolean;
sx?: SxProps<Theme>;
} & ClassNameProps
>;

Expand All @@ -66,10 +45,10 @@ export const CollapsibleSection = forwardRef<
children,
keepRendered,
icon,
sx,
},
ref,
) => {
const classes = useStyles();
const [internalExpanded, setInternalExpanded] = useState(startExpanded);
const finalExpanded = expanded !== undefined ? expanded : internalExpanded;

Expand All @@ -79,17 +58,39 @@ export const CollapsibleSection = forwardRef<
};

return (
<div ref={ref} className={className}>
<Box ref={ref} className={className} sx={sx}>
<Box display="flex" flexDirection="row" alignItems="center">
<Typography
className={classes.title}
sx={{
display: "flex",
flexDirection: "row",
flexWrap: "nowrap",
alignItems: "center",
fontWeight: 500,
cursor: "pointer",
marginRight: 1,
}}
variant="h4"
onClick={handleExpandClick}
>
{finalExpanded ? (
<RiArrowDownSLine className={classes.icon} />
<Box
component={RiArrowDownSLine}
sx={{
marginRight: 1,
width: 24,
height: 24,
}}
/>
) : (
<RiArrowRightSLine className={classes.icon} />
<Box
component={RiArrowRightSLine}
sx={{
marginRight: 1,
width: 24,
height: 24,
}}
/>
)}
{title}
</Typography>
Expand All @@ -98,22 +99,11 @@ export const CollapsibleSection = forwardRef<
<HideableBlock visible={finalExpanded} keepRendered={keepRendered}>
{children}
</HideableBlock>
</div>
</Box>
);
},
);

const useHideableBlockStyles = makeStyles((theme) =>
createStyles({
body: {
marginTop: theme.spacing(1),
},
bodyHidden: {
display: "none",
},
}),
);

type HideableBlockProps = PropsWithChildren<
{
visible: boolean;
Expand All @@ -135,8 +125,6 @@ export const HideableBlock = ({
keepRendered,
children,
}: HideableBlockProps) => {
const classes = useHideableBlockStyles();

// visible represents whether the component is viewable in the browser.
// Rendered represents whether the DOM elements exist in the DOM tree.
// If !visible && rendered, then the elements are in the DOM but are
Expand All @@ -152,12 +140,13 @@ export const HideableBlock = ({
// Optimization to keep the component rendered (but not visible) when hidden
// to avoid re-rendering when component is shown again.
return visible || (keepRendered && rendered) ? (
<div
className={classNames(classes.body, {
[classes.bodyHidden]: !visible,
})}
<Box
sx={{
marginTop: 1,
display: !visible ? "none" : "block",
}}
>
{children}
</div>
</Box>
) : null;
};
Loading
Loading