in superset-frontend/src/features/home/Menu.tsx [142:324]
export function Menu({
data: {
menu,
brand,
navbar_right: navbarRight,
settings,
environment_tag: environmentTag,
},
isFrontendRoute = () => false,
}: MenuProps) {
const [showMenu, setMenu] = useState<MenuMode>('horizontal');
const screens = useBreakpoint();
const uiConfig = useUiConfig();
useEffect(() => {
function handleResize() {
if (window.innerWidth <= 767) {
setMenu('inline');
} else setMenu('horizontal');
}
handleResize();
const windowResize = debounce(() => handleResize(), 10);
window.addEventListener('resize', windowResize);
return () => window.removeEventListener('resize', windowResize);
}, []);
enum Paths {
Explore = '/explore',
Dashboard = '/dashboard',
Chart = '/chart',
Datasets = '/tablemodelview',
}
const defaultTabSelection: string[] = [];
const [activeTabs, setActiveTabs] = useState(defaultTabSelection);
const location = useLocation();
useEffect(() => {
const path = location.pathname;
switch (true) {
case path.startsWith(Paths.Dashboard):
setActiveTabs(['Dashboards']);
break;
case path.startsWith(Paths.Chart) || path.startsWith(Paths.Explore):
setActiveTabs(['Charts']);
break;
case path.startsWith(Paths.Datasets):
setActiveTabs(['Datasets']);
break;
default:
setActiveTabs(defaultTabSelection);
}
}, [location.pathname]);
const standalone = getUrlParam(URL_PARAMS.standalone);
if (standalone || uiConfig.hideNav) return <></>;
const renderSubMenu = ({
label,
childs,
url,
index,
isFrontendRoute,
}: MenuObjectProps) => {
if (url && isFrontendRoute) {
return (
<MainNav.Item key={label} role="presentation">
<NavLink role="button" to={url} activeClassName="is-active">
{label}
</NavLink>
</MainNav.Item>
);
}
if (url) {
return (
<MainNav.Item key={label}>
<a href={url}>{label}</a>
</MainNav.Item>
);
}
return (
<StyledSubMenu
key={index}
title={label}
icon={
showMenu === 'inline' ? (
<></>
) : (
<Icons.CaretDownOutlined iconSize="xs" />
)
}
>
{childs?.map((child: MenuObjectChildProps | string, index1: number) => {
if (typeof child === 'string' && child === '-' && label !== 'Data') {
return <MainNav.Divider key={`$${index1}`} />;
}
if (typeof child !== 'string') {
return (
<MainNav.Item key={`${child.label}`}>
{child.isFrontendRoute ? (
<NavLink
to={child.url || ''}
exact
activeClassName="is-active"
>
{child.label}
</NavLink>
) : (
<a href={child.url}>{child.label}</a>
)}
</MainNav.Item>
);
}
return null;
})}
</StyledSubMenu>
);
};
return (
<StyledHeader className="top" id="main-menu" role="navigation">
<Row>
<Col md={16} xs={24}>
<Tooltip
id="brand-tooltip"
placement="bottomLeft"
title={brand.tooltip}
arrow={{ pointAtCenter: true }}
>
{isFrontendRoute(window.location.pathname) ? (
<GenericLink className="navbar-brand" to={brand.path}>
<img src={brand.icon} alt={brand.alt} />
</GenericLink>
) : (
<a className="navbar-brand" href={brand.path} tabIndex={-1}>
<img src={brand.icon} alt={brand.alt} />
</a>
)}
</Tooltip>
{brand.text && (
<div className="navbar-brand-text">
<span>{brand.text}</span>
</div>
)}
<MainNav
mode={showMenu}
data-test="navbar-top"
className="main-nav"
selectedKeys={activeTabs}
disabledOverflow
>
{menu.map((item, index) => {
const props = {
index,
...item,
isFrontendRoute: isFrontendRoute(item.url),
childs: item.childs?.map(c => {
if (typeof c === 'string') {
return c;
}
return {
...c,
isFrontendRoute: isFrontendRoute(c.url),
};
}),
};
return renderSubMenu(props);
})}
</MainNav>
</Col>
<Col md={8} xs={24}>
<RightMenu
align={screens.md ? 'flex-end' : 'flex-start'}
settings={settings}
navbarRight={navbarRight}
isFrontendRoute={isFrontendRoute}
environmentTag={environmentTag}
/>
</Col>
</Row>
</StyledHeader>
);
}