/ frontend / src / app / components / MatxVerticalNav / MatxVerticalNav.jsx
MatxVerticalNav.jsx
  1  import { Fragment } from "react";
  2  import { NavLink } from "react-router-dom";
  3  import { Box, ButtonBase, Icon, styled } from "@mui/material";
  4  
  5  import useSettings from "app/hooks/useSettings";
  6  import { Paragraph, Span } from "../Typography";
  7  import MatxVerticalNavExpansionPanel from "./MatxVerticalNavExpansionPanel";
  8  
  9  const ListLabel = styled(Paragraph)(({ theme, mode }) => ({
 10    fontSize: "12px",
 11    marginTop: "20px",
 12    marginLeft: "15px",
 13    marginBottom: "10px",
 14    textTransform: "uppercase",
 15    display: mode === "compact" && "none",
 16    color: theme.palette.text.secondary
 17  }));
 18  
 19  const ExtAndIntCommon = {
 20    display: "flex",
 21    overflow: "hidden",
 22    borderRadius: "4px",
 23    height: 44,
 24    whiteSpace: "pre",
 25    marginBottom: "8px",
 26    textDecoration: "none",
 27    justifyContent: "space-between",
 28    transition: "all 150ms ease-in",
 29    "&:hover": { background: "rgba(255, 255, 255, 0.08)" },
 30    "&.compactNavItem": {
 31      overflow: "hidden",
 32      justifyContent: "center !important"
 33    },
 34    "& .icon": {
 35      fontSize: "18px",
 36      paddingLeft: "16px",
 37      paddingRight: "16px",
 38      verticalAlign: "middle"
 39    }
 40  };
 41  const ExternalLink = styled("a")(({ theme }) => ({
 42    ...ExtAndIntCommon,
 43    color: theme.palette.text.primary
 44  }));
 45  
 46  const InternalLink = styled(Box)(({ theme }) => ({
 47    "& a": {
 48      ...ExtAndIntCommon,
 49      color: theme.palette.text.primary
 50    },
 51    "& .navItemActive": {
 52      backgroundColor: "rgba(255, 255, 255, 0.16)"
 53    }
 54  }));
 55  
 56  const StyledText = styled(Span)(({ mode }) => ({
 57    fontSize: "0.875rem",
 58    paddingLeft: "0.8rem",
 59    display: mode === "compact" && "none"
 60  }));
 61  
 62  const BulletIcon = styled("div")(({ theme }) => ({
 63    padding: "2px",
 64    marginLeft: "24px",
 65    marginRight: "8px",
 66    overflow: "hidden",
 67    borderRadius: "300px",
 68    background: theme.palette.text.primary
 69  }));
 70  
 71  const BadgeValue = styled("div")(() => ({
 72    padding: "1px 8px",
 73    overflow: "hidden",
 74    borderRadius: "300px"
 75  }));
 76  
 77  export default function MatxVerticalNav({ items }) {
 78    const { settings } = useSettings();
 79    const { mode } = settings.layout1Settings.leftSidebar;
 80  
 81    const renderLevels = (data) => {
 82      return data.map((item, index) => {
 83        if (item.type === "label")
 84          return (
 85            <ListLabel key={index} mode={mode} className="sidenavHoverShow">
 86              {item.label}
 87            </ListLabel>
 88          );
 89  
 90        if (item.children) {
 91          return (
 92            <MatxVerticalNavExpansionPanel mode={mode} item={item} key={index}>
 93              {renderLevels(item.children)}
 94            </MatxVerticalNavExpansionPanel>
 95          );
 96        } else if (item.type === "extLink") {
 97          return (
 98            <ExternalLink
 99              key={index}
100              href={item.path}
101              className={`${mode === "compact" && "compactNavItem"}`}
102              rel="noopener noreferrer"
103              target="_blank">
104              <ButtonBase key={item.name} name="child" sx={{ width: "100%" }}>
105                {(() => {
106                  if (item.icon) {
107                    return <Icon className="icon">{item.icon}</Icon>;
108                  } else {
109                    return <span className="item-icon icon-text">{item.iconText}</span>;
110                  }
111                })()}
112                <StyledText mode={mode} className="sidenavHoverShow">
113                  {item.name}
114                </StyledText>
115                <Box mx="auto"></Box>
116                {item.badge && <BadgeValue>{item.badge.value}</BadgeValue>}
117              </ButtonBase>
118            </ExternalLink>
119          );
120        } else {
121          return (
122            <InternalLink key={index}>
123              <NavLink
124                to={item.path}
125                className={({ isActive }) =>
126                  isActive
127                    ? `navItemActive ${mode === "compact" && "compactNavItem"}`
128                    : `${mode === "compact" && "compactNavItem"}`
129                }>
130                <ButtonBase key={item.name} name="child" sx={{ width: "100%" }}>
131                  {item?.icon ? (
132                    <Icon className="icon" sx={{ width: 36 }}>
133                      {item.icon}
134                    </Icon>
135                  ) : (
136                    <Fragment>
137                      <BulletIcon
138                        className={`nav-bullet`}
139                        sx={{ display: mode === "compact" && "none" }}
140                      />
141                      <Box
142                        className="nav-bullet-text"
143                        sx={{
144                          ml: "20px",
145                          fontSize: "11px",
146                          display: mode !== "compact" && "none"
147                        }}>
148                        {item.iconText}
149                      </Box>
150                    </Fragment>
151                  )}
152                  <StyledText mode={mode} className="sidenavHoverShow">
153                    {item.name}
154                  </StyledText>
155  
156                  <Box mx="auto" />
157  
158                  {item.badge && (
159                    <BadgeValue className="sidenavHoverShow">{item.badge.value}</BadgeValue>
160                  )}
161                </ButtonBase>
162              </NavLink>
163            </InternalLink>
164          );
165        }
166      });
167    };
168  
169    return <div className="navigation">{renderLevels(items)}</div>;
170  }