headlamp icon indicating copy to clipboard operation
headlamp copied to clipboard

frontend: Remove makeStyles and use sx

Open illume opened this issue 10 months ago • 4 comments

illume avatar Apr 15 '24 13:04 illume

diff --git a/frontend/src/components/Sidebar/ListItemLink.tsx b/frontend/src/components/Sidebar/ListItemLink.tsx
index 43cf9bb8..c7661978 100644
--- a/frontend/src/components/Sidebar/ListItemLink.tsx
+++ b/frontend/src/components/Sidebar/ListItemLink.tsx
@@ -3,24 +3,22 @@ import { Tooltip } from '@mui/material';
 import ListItem from '@mui/material/ListItem';
 import ListItemIcon from '@mui/material/ListItemIcon';
 import ListItemText from '@mui/material/ListItemText';
-import withStyles from '@mui/styles/withStyles';
+import { styled } from '@mui/system';
 import React from 'react';
 import { Link as RouterLink, LinkProps as RouterLinkProps } from 'react-router-dom';
 
 const ExpandedIconSize = 20;
 const CollapsedIconSize = 24;
 
-const IconTooltip = withStyles(() => ({
-  tooltip: {
-    backgroundColor: '#474747',
-    color: '#fff',
-    minWidth: 60,
-    padding: '0.5rem',
-    fontSize: '0.8rem',
-    border: '1px solid #474747',
-    marginLeft: '1rem',
-  },
-}))(Tooltip);
+const IconTooltip = styled(Tooltip)(() => ({
+  backgroundColor: '#474747',
+  color: '#fff',
+  minWidth: 60,
+  padding: '0.5rem',
+  fontSize: '0.8rem',
+  border: '1px solid #474747',
+  marginLeft: '1rem',
+}));
 
 interface ListItemLinkProps {
   primary: string;
diff --git a/frontend/src/components/authchooser/index.tsx b/frontend/src/components/authchooser/index.tsx
index 0c4616e3..10754224 100644
--- a/frontend/src/components/authchooser/index.tsx
+++ b/frontend/src/components/authchooser/index.tsx
@@ -1,6 +1,6 @@
 import { InlineIcon } from '@iconify/react';
 import { Box, Button } from '@mui/material';
-import withStyles from '@mui/styles/withStyles';
+import { styled } from '@mui/system';
 import _ from 'lodash';
 import React from 'react';
 import { useTranslation } from 'react-i18next';
@@ -18,18 +18,16 @@ import { DialogTitle } from '../common/Dialog';
 import Empty from '../common/EmptyContent';
 import OauthPopup from '../oidcauth/OauthPopup';
 
-const ColorButton = withStyles(theme => ({
-  root: {
-    color: theme.palette.primary.contrastText,
-    backgroundColor: theme.palette.primaryColor,
-    width: '14rem',
-    padding: '0.5rem 2rem',
-    '&:hover': {
-      opacity: '0.8',
-      backgroundColor: theme.palette.text.primary,
-    },
+const ColorButton = styled(Button)(({ theme }) => ({
+  color: theme.palette.primary.contrastText,
+  backgroundColor: theme.palette.primaryColor,
+  width: '14rem',
+  padding: '0.5rem 2rem',
+  '&:hover': {
+    opacity: '0.8',
+    backgroundColor: theme.palette.text.primary,
   },
-}))(Button);
+}));
 
 interface ReactRouterLocationStateIface {
   from?: Location;
diff --git a/frontend/src/components/common/Resource/EditorDialog.tsx b/frontend/src/components/common/Resource/EditorDialog.tsx
index a36bd225..899398ca 100644
--- a/frontend/src/components/common/Resource/EditorDialog.tsx
+++ b/frontend/src/components/common/Resource/EditorDialog.tsx
@@ -8,7 +8,6 @@ import FormControlLabel from '@mui/material/FormControlLabel';
 import FormGroup from '@mui/material/FormGroup';
 import Switch from '@mui/material/Switch';
 import Typography from '@mui/material/Typography';
-import makeStyles from '@mui/styles/makeStyles';
 import * as yaml from 'js-yaml';
 import React from 'react';
 import { useTranslation } from 'react-i18next';
@@ -32,31 +31,6 @@ if (process.env.NODE_ENV === 'test') {
   monaco = require('monaco-editor');
 }
 
-const useStyle = makeStyles(theme => ({
-  dialogContent: {
-    height: '80%',
-    // minHeight: '600px',
-    overflowY: 'hidden',
-  },
-  terminalCode: {
-    color: theme.palette.common.white,
-  },
-  terminal: {
-    backgroundColor: theme.palette.common.black,
-    height: '500px',
-    width: '100%',
-    overflow: 'scroll',
-    marginTop: theme.spacing(3),
-  },
-  containerFormControl: {
-    minWidth: '11rem',
-  },
-  scrollable: {
-    overflowY: 'auto',
-    overflowX: 'hidden',
-  },
-}));
-
 type KubeObjectIsh = Partial<KubeObjectInterface>;
 
 export interface EditorDialogProps extends DialogProps {
@@ -85,7 +59,6 @@ export default function EditorDialog(props: EditorDialogProps) {
   };
   const { i18n } = useTranslation();
   const [lang, setLang] = React.useState(i18n.language);
-  const classes = useStyle();
   const themeName = getThemeName();
 
   const originalCodeRef = React.useRef({ code: '', format: item ? 'yaml' : '' });
@@ -336,7 +309,12 @@ export default function EditorDialog(props: EditorDialogProps) {
         <Loader title={t('Loading editor')} />
       ) : (
         <React.Fragment>
-          <DialogContent className={classes.dialogContent}>
+          <DialogContent
+            sx={{
+              height: '80%',
+              overflowY: 'hidden',
+            }}
+          >
             <Box display="flex" flexDirection="row-reverse">
               <Box p={1}>
                 <FormGroup row>
@@ -367,7 +345,15 @@ export default function EditorDialog(props: EditorDialogProps) {
                   {
                     label: t('translation|Documentation'),
                     component: (
-                      <Box p={2} className={classes.scrollable} maxHeight={600} height={600}>
+                      <Box
+                        p={2}
+                        sx={{
+                          overflowY: 'auto',
+                          overflowX: 'hidden',
+                        }}
+                        maxHeight={600}
+                        height={600}
+                      >
                         <DocsViewer docSpecs={docSpecs} />
                       </Box>
                     ),
diff --git a/frontend/src/components/common/ShowHideLabel/ShowHideLabel.tsx b/frontend/src/components/common/ShowHideLabel/ShowHideLabel.tsx
index d8dd3abb..19297540 100644
--- a/frontend/src/components/common/ShowHideLabel/ShowHideLabel.tsx
+++ b/frontend/src/components/common/ShowHideLabel/ShowHideLabel.tsx
@@ -1,15 +1,8 @@
 import { Icon } from '@iconify/react';
 import { Box, IconButton } from '@mui/material';
-import makeStyles from '@mui/styles/makeStyles';
 import React from 'react';
 import { useTranslation } from 'react-i18next';
 
-const useStyles = makeStyles({
-  fullText: {
-    wordBreak: 'break-all',
-  },
-});
-
 export interface ShowHideLabelProps {
   children: string;
   show?: boolean;
@@ -21,7 +14,6 @@ export default function ShowHideLabel(props: ShowHideLabelProps) {
   const { show = false, labelId = '', maxChars = 256, children } = props;
   const { t } = useTranslation();
   const [expanded, setExpanded] = React.useState(show);
-  const classes = useStyles();
 
   const labelIdOrRandom = React.useMemo(() => {
     if (!!labelId || !!process.env.UNDER_TEST) {
@@ -51,7 +43,7 @@ export default function ShowHideLabel(props: ShowHideLabelProps) {
     <Box display={expanded ? 'block' : 'flex'}>
       <label
         id={labelIdOrRandom}
-        className={classes.fullText}
+        style={{wordBreak: 'break-all',}}
         aria-expanded={!needsButton ? undefined : expanded}
       >
         {actualText}

I was also work on some of them. here is my current state of others.

farodin91 avatar Apr 17 '24 20:04 farodin91

import { Grid, GridProps } from '@mui/material';
import React from 'react';
import { ValueLabel } from '../Label';

export interface NameValueTableRow {
  /** The name (key) for this row */
  name: string | JSX.Element;
  /** The value for this row */
  value?: string | JSX.Element | JSX.Element[];
  /** Whether this row should be hidden (can be a boolean or a function that will take the
   * @param value and return a boolean) */
  hide?: boolean | ((value: NameValueTableRow['value']) => boolean);
  /** Extra properties to pass to the value cell */
  valueCellProps?: GridProps;
  /** Whether to highlight the row (used for titles, separators, etc.). */
  withHighlightStyle?: boolean;
}

export interface NameValueTableProps {
  rows: NameValueTableRow[];
  valueCellProps?: GridProps;
}

function Value({
  value,
}: {
  value: string | JSX.Element | JSX.Element[] | undefined;
}): JSX.Element | null {
  if (typeof value === 'undefined') {
    return null;
  } else if (typeof value === 'string') {
    return <ValueLabel>{value}</ValueLabel>;
  } else if (Array.isArray(value)) {
    return (
      <>
        {value.map((val, i) => (
          <Value value={val} key={i} />
        ))}
      </>
    );
  } else {
    return value;
  }
}

export default function NameValueTable(props: NameValueTableProps) {
  const { rows, valueCellProps: globalValueCellProps } = props;

  const visibleRows = React.useMemo(
    () =>
      rows.filter(({ value, hide = false }) => {
        let shouldHide = false;
        if (typeof hide === 'function') {
          shouldHide = hide(value);
        } else {
          shouldHide = hide;
        }

        return !shouldHide;
      }),
    [rows]
  );

  return (
    <Grid
      container
      component="dl" // mount a Definition List
      sx={theme => ({
        border: '1px solid #e7e7e7',
        borderRadius: theme.shape.borderRadius,
      })}
    >
      {visibleRows.flatMap(
        ({ name, value, hide = false, withHighlightStyle = false, valueCellProps = {} }, i) => {
          let shouldHide = false;
          if (typeof hide === 'function') {
            shouldHide = hide(value);
          } else {
            shouldHide = hide;
          }

          if (shouldHide) {
            return null;
          }

          const last = visibleRows.length === i + 1;
          const { className, ...otherValueCellProps } = globalValueCellProps || {};

          const hideValueGridItem = withHighlightStyle && !value;

          const items = [
            <Grid
              item
              key={i}
              xs={12}
              sm={hideValueGridItem ? 12 : 4}
              component="dt"
              sx={theme => {
                let extra = withHighlightStyle
                  ? {
                      color: theme.palette.tables.head.color,
                      fontWeight: 'bold',
                      background: theme.palette.tables.head.background,
                    }
                  : {};
                return {
                  fontSize: '1rem',
                  textAlign: 'left',
                  maxWidth: '100%',
                  minWidth: '10rem',
                  verticalAlign: 'top',
                  color: theme.palette.text.secondary,
                  borderBottom: last ? 'none' : `1px solid ${theme.palette.divider}`,
                  padding: '7px 12px',
                  [theme.breakpoints.down('sm')]: {
                    color: theme.palette.text.primary,
                    fontSize: '1.5rem',
                    minWidth: '100%',
                    width: '100%',
                    maxWidth: '100%',
                    display: 'block',
                    borderTop: `1px solid ${theme.palette.divider}`,
                    borderBottom: `none`,
                  },
                  ...extra,
                };
              }}
            >
              {name}
            </Grid>,
          ];
          if (!hideValueGridItem) {
            items.push(
              <Grid
                item
                key={i + 10000}
                xs={12}
                sm={8}
                component="dd"
                sx={theme => {
                  let extra = withHighlightStyle
                    ? {
                        color: theme.palette.tables.head.color,
                        fontWeight: 'bold',
                        background: theme.palette.tables.head.background,
                      }
                    : {};
                  return {
                    width: '100%',
                    verticalAlign: 'top',
                    fontSize: '1rem',
                    overflowWrap: 'anywhere',
                    padding: '7px 12px',
                    borderBottom: last ? 'none' : `1px solid ${theme.palette.divider}`,
                    [theme.breakpoints.down('sm')]: {
                      color: theme.palette.text.secondary,
                      minWidth: '100%',
                      width: '100%',
                      maxWidth: '100%',
                      display: 'block',
                      marginBottom: '2rem',
                      borderBottom: `none`,
                    },
                    ...extra,
                  };
                }}
                {...otherValueCellProps}
                {...valueCellProps}
              >
                <Value value={value} />
              </Grid>
            );
          }
          return items;
        }
      )}
    </Grid>
  );
}

My work on NameValueTable.

farodin91 avatar Apr 17 '24 21:04 farodin91

Hey @farodin91 thanks! I'll add your changes in here and add you as a co author to all the commits if that's ok?

illume avatar Apr 18 '24 10:04 illume

Sounds good to me!

farodin91 avatar Apr 18 '24 10:04 farodin91

@farodin91 this should be the last of it.

I left mui/styles in there still for a little while longer for backwards compatibility for any plugins that might still be using it. This should the only mui/styles left as far as I know.

illume avatar May 06 '24 15:05 illume

Thanks @illume . If this conflicts with #1921 , I think it's probably easier to merge the table first?

joaquimrocha avatar May 06 '24 15:05 joaquimrocha

@joaquimrocha I don't expect a conflict would be more than a few lines, and probably generating the snapshots again. (I would suggest just merging which ever one is ready when it can be merged)

illume avatar May 08 '24 07:05 illume

I merged a couple of PRs into main and there was a conflict. Fixed and rebased against main again.

illume avatar May 13 '24 07:05 illume

Rebased from main again. (the table PR was merged, and a few conflicts were fixed)

WIP, doing a retest...

illume avatar May 14 '24 14:05 illume

Thanks a lot for such a comprehensive and important work, @farodin91 and @illume !

joaquimrocha avatar May 17 '24 13:05 joaquimrocha