import { Box, Breadcrumbs, Chip, IconButton, Link, LinkProps, Skeleton, Theme, useTheme } from "@mui/material"; import { Replay } from "@mui/icons-material"; import { useMobile } from "hooks"; import { ReactNode } from "react"; import { useLocation } from "react-router"; import { Link as RouterLink } from "react-router-dom"; import { or } from "utils/types"; import { makeStyles } from "@mui/styles"; import { getThemeType } from "theme/themeType"; const useStyles = makeStyles((theme: Theme) => { // const isMobile = useMobile() return ({ chip: { maxWidth: "150px", [theme.breakpoints.up("md")]: { maxWidth: "200px" }, color: "inherit", textDecoration: "none", '&:hover': { color: "inherit" } }, textOverflow: { whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", textTransform: "capitalize", textDecoration: "none" } }); }); interface Props { deviceName?: string; componentName?: string; groupName?: string; binName?: string; reportTarget?: string; loading?: boolean; reload?: () => void; padding?: number; paddingLeft?: number; paddingRight?: number; paddingTop?: number; paddingBottom?: number; prependPaths?: string[]; } interface LinkRouterProps extends LinkProps { to: string; replace?: boolean; } const LinkRouter = (props: LinkRouterProps) => ; export default function SmartBreadcrumb(props: Props) { const prependPaths = props.prependPaths; const theme = useTheme(); const location = useLocation(); const isMobile = useMobile(); const classes = useStyles(); const { loading, reload } = props; const groupID = (): string => { let index = prependPaths?.indexOf("groups") if (index !== undefined && index > -1) { if (prependPaths && prependPaths[index+1]) { return prependPaths[index+1] } } const regexMatch = or(location.pathname.match(/\/groups\/([^/]+)/), []) return or(regexMatch[1], "0").toString(); }; const deviceID = (): string => { const regexMatch = or(location.pathname.match(/\/devices\/([^/]+)/), []) return or(regexMatch[1], "0").toString(); }; const mineKey = (): string => { const regexMatch = or(location.pathname.match(/\/mines\/([^/]+)/), []) return or(regexMatch[1], "0").toString(); }; const jobsiteKey = (): string => { const regexMatch = or(location.pathname.match(/\/jobs\/([^/]+)/), []) return or(regexMatch[1], "0").toString(); }; const componentID = (): string => { const regexMatch = or(location.pathname.match(/\/components\/([^/]+)/), []) return or(regexMatch[1], "0").toString(); }; const reportID = (): string => { const regexMatch = or(location.pathname.match(/\/reports\/([^/]+)/), []) return or(regexMatch[1], "0").toString(); }; const binID = (): string => { const regexMatch = or(location.pathname.match(/\/bins\/([^/]+)/), []) return or(regexMatch[1], "0").toString(); }; const reportIDShort = (): string => { return reportID().split("-")[0]; }; // Paths const dashboardPath = (): string => { return "/"; }; const groupsPath = (): string => { return "/groups"; }; const groupPath = (): string => { return groupsPath() + "/" + groupID(); }; const devicesPath = (): string => { return "/devices"; }; const devicePath = (): string => { return devicesPath() + "/" + deviceID(); }; const minesPath = (): string => { return "/mines"; }; const minePath = (): string => { return minesPath() + "/" + mineKey(); }; const jobsitesPath = (): string => { return "/jobsites"; }; const jobsitePath = (): string => { return jobsitesPath() + "/" + jobsiteKey(); }; const componentsPath = (): string => { return "/components"; }; const componentPath = (): string => { return componentsPath() + "/" + componentID(); }; const securityPath = (): string => { return "/security"; }; const reportPath = (): string => { return securityPath() + "/" + reportID(); }; const groupDevicesPath = (): string => { return groupPath() + devicesPath(); }; const groupDevicePath = (): string => { return groupPath() + devicePath(); }; const groupComponentsPath = (): string => { return groupPath() + componentsPath(); }; const groupComponentPath = (): string => { return groupPath() + componentPath(); }; const historyPath = (): string => { return "/history"; }; const deviceHistoryPath = (): string => { return devicePath() + historyPath(); }; const groupDeviceHistoryPath = (): string => { return groupDevicePath() + historyPath(); }; const firmwarePath = (): string => { return "/firmware"; }; const usersPath = (): string => { return "/users"; }; const binsPath = (): string => { return "/bins"; }; const binPath = (): string => { return binsPath() + "/" + binID(); }; const teamsPath = (): string => { return "/teams"; } const getBreadcrumbMap = (): { [key: string]: string } => { const { groupName, deviceName, componentName, reportTarget, binName } = props; const deviceLabel: string = deviceName ? deviceName : "Device " + deviceID(); const componentLabel: string = componentName ? componentName : "Component " + componentID(); const binLabel: string = binName ?? "Bin " + binID(); const mineLabel: string = "Mine Site"; const jobsiteLabel: string = "Job Site"; return { [dashboardPath()]: "Dashboard", [groupsPath()]: "Groups", [groupPath()]: groupName ? groupName : "Group " + groupID(), [devicesPath()]: "Devices", [devicePath()]: deviceLabel, [minesPath()]: "Mines", [minePath()]: mineLabel, [jobsitesPath()]: "Job Sites", [jobsitePath()]: jobsiteLabel, [componentsPath()]: "Components", [componentPath()]: componentLabel, [securityPath()]: "Security", [reportPath()]: "Report " + reportIDShort() + (reportTarget ? " (" + reportTarget + ")" : ""), [groupDevicePath()]: deviceLabel, [groupComponentPath()]: componentLabel, [deviceHistoryPath()]: "History", [groupDeviceHistoryPath()]: "History", [firmwarePath()]: "Firmware", [usersPath()]: "Users", [binsPath()]: "Bins", [binPath()]: binLabel, [teamsPath()]: "Teams" }; }; const breadcrumbBlacklist = (): string[] => { return [dashboardPath(), componentsPath(), groupDevicesPath(), groupComponentsPath()]; }; const breadcrumbLinks = (): ReactNode[] => { const breadcrumbMap = getBreadcrumbMap(); //console.log(breadcrumbMap) let links: ReactNode[] = []; let pathnames = location.pathname.split("/").filter((x: any) => x); const blacklist = breadcrumbBlacklist(); if (pathnames.length < 1) { return [linkComponent("/", "Dashboard", true)]; } if (prependPaths) pathnames.unshift(...prependPaths) //console.log(pathnames) pathnames.forEach((_value: any, index: any) => { const lastPath = index === pathnames.length - 1; //console.log(lastPath) const to = `/${pathnames.slice(0, index + 1).join("/")}`; //console.log("to: " + to) let label = breadcrumbMap[to]; //console.log("label: "+label) let result = to.split("/").filter(str => str !== ""); //console.log("result: " + result.toString()) if (!label) { //console.log("no label") if (result.length > 1) { if (result[result.length - 1] !== "components") { label = breadcrumbMap["/" + result[result.length - 1]]; } } if (!label && result[result.length - 1] !== "components") { label = breadcrumbMap["/" + result[result.length - 2] + "/" + result[result.length - 1]]; } } if (!blacklist.includes(to) && label) { //console.log("push link") links.push(linkComponent(to, label, lastPath)); } }); //console.log(links) return links; }; const linkComponent = (to: string, label: string, lastPath: boolean) => { return ( {label} } className={classes.chip} /> ); }; const localReload = () => { if (reload) { reload(); } else { } }; if (loading === true) return ; return ( {breadcrumbLinks()} {reload && ( )} ); }