mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
SingleTopNav: Add "Grafana" header to MegaMenu (#93798)
* add "Grafana" header to MegaMenu * add truncation for really long custom app titles * revert padding change since paddingLeft will handle it
This commit is contained in:
parent
0e4c90dd87
commit
bc6752a51c
@ -91,7 +91,7 @@ const getStyles = (theme: GrafanaTheme2, searchBarHidden?: boolean) => {
|
||||
left: 0,
|
||||
position: 'fixed',
|
||||
right: 0,
|
||||
top: searchBarHidden ? 0 : TOP_BAR_LEVEL_HEIGHT,
|
||||
top: searchBarHidden || config.featureToggles.singleTopNav ? 0 : TOP_BAR_LEVEL_HEIGHT,
|
||||
zIndex: theme.zIndex.modalBackdrop,
|
||||
|
||||
[theme.breakpoints.up('md')]: {
|
||||
@ -107,7 +107,7 @@ const getStyles = (theme: GrafanaTheme2, searchBarHidden?: boolean) => {
|
||||
// Needs to below navbar should we change the navbarFixed? add add a new level?
|
||||
zIndex: theme.zIndex.modal,
|
||||
position: 'fixed',
|
||||
top: searchBarHidden ? 0 : TOP_BAR_LEVEL_HEIGHT,
|
||||
top: searchBarHidden || config.featureToggles.singleTopNav ? 0 : TOP_BAR_LEVEL_HEIGHT,
|
||||
backgroundColor: theme.colors.background.primary,
|
||||
flex: '1 1 0',
|
||||
|
||||
|
@ -13,6 +13,7 @@ import { setBookmark } from 'app/core/reducers/navBarTree';
|
||||
import { usePatchUserPreferencesMutation } from 'app/features/preferences/api/index';
|
||||
import { useDispatch, useSelector } from 'app/types';
|
||||
|
||||
import { MegaMenuHeader } from './MegaMenuHeader';
|
||||
import { MegaMenuItem } from './MegaMenuItem';
|
||||
import { usePinnedItems } from './hooks';
|
||||
import { enrichWithInteractionTracking, findByUrl, getActiveItem } from './utils';
|
||||
@ -62,6 +63,10 @@ export const MegaMenu = memo(
|
||||
|
||||
const activeItem = getActiveItem(navItems, state.sectionNav.node, location.pathname);
|
||||
|
||||
const handleMegaMenu = () => {
|
||||
chrome.setMegaMenuOpen(!state.megaMenuOpen);
|
||||
};
|
||||
|
||||
const handleDockedMenu = () => {
|
||||
chrome.setMegaMenuDocked(!state.megaMenuDocked);
|
||||
if (state.megaMenuDocked) {
|
||||
@ -109,22 +114,26 @@ export const MegaMenu = memo(
|
||||
|
||||
return (
|
||||
<div data-testid={selectors.components.NavMenu.Menu} ref={ref} {...restProps}>
|
||||
<div className={styles.mobileHeader}>
|
||||
<Icon name="bars" size="xl" />
|
||||
<IconButton
|
||||
tooltip={t('navigation.megamenu.close', 'Close menu')}
|
||||
name="times"
|
||||
onClick={onClose}
|
||||
size="xl"
|
||||
variant="secondary"
|
||||
/>
|
||||
</div>
|
||||
{config.featureToggles.singleTopNav ? (
|
||||
<MegaMenuHeader handleDockedMenu={handleDockedMenu} handleMegaMenu={handleMegaMenu} onClose={onClose} />
|
||||
) : (
|
||||
<div className={styles.mobileHeader}>
|
||||
<Icon name="bars" size="xl" />
|
||||
<IconButton
|
||||
tooltip={t('navigation.megamenu.close', 'Close menu')}
|
||||
name="times"
|
||||
onClick={onClose}
|
||||
size="xl"
|
||||
variant="secondary"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<nav className={styles.content}>
|
||||
<CustomScrollbar showScrollIndicators hideHorizontalTrack>
|
||||
<ul className={styles.itemList} aria-label={t('navigation.megamenu.list-label', 'Navigation')}>
|
||||
{navItems.map((link, index) => (
|
||||
<Stack key={link.text} direction={index === 0 ? 'row-reverse' : 'row'} alignItems="start">
|
||||
{index === 0 && (
|
||||
{index === 0 && !config.featureToggles.singleTopNav && (
|
||||
<IconButton
|
||||
id="dock-menu-button"
|
||||
className={styles.dockMenuButton}
|
||||
|
@ -0,0 +1,85 @@
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { IconButton, Stack, Text, ToolbarButton, useTheme2 } from '@grafana/ui';
|
||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { Branding } from '../../Branding/Branding';
|
||||
import { TOP_BAR_LEVEL_HEIGHT } from '../types';
|
||||
|
||||
export interface Props {
|
||||
handleMegaMenu: () => void;
|
||||
handleDockedMenu: () => void;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export function MegaMenuHeader({ handleMegaMenu, handleDockedMenu, onClose }: Props) {
|
||||
const theme = useTheme2();
|
||||
const { chrome } = useGrafana();
|
||||
const state = chrome.useState();
|
||||
const styles = getStyles(theme);
|
||||
|
||||
return (
|
||||
<div className={styles.header}>
|
||||
<Stack alignItems="center" minWidth={0}>
|
||||
<ToolbarButton narrow onClick={handleMegaMenu}>
|
||||
<Branding.MenuLogo className={styles.img} />
|
||||
</ToolbarButton>
|
||||
<Text truncate>{Branding.AppTitle}</Text>
|
||||
</Stack>
|
||||
<IconButton
|
||||
id="dock-menu-button"
|
||||
className={styles.dockMenuButton}
|
||||
tooltip={
|
||||
state.megaMenuDocked
|
||||
? t('navigation.megamenu.undock', 'Undock menu')
|
||||
: t('navigation.megamenu.dock', 'Dock menu')
|
||||
}
|
||||
name="web-section-alt"
|
||||
onClick={handleDockedMenu}
|
||||
variant="secondary"
|
||||
/>
|
||||
<IconButton
|
||||
className={styles.mobileCloseButton}
|
||||
tooltip={t('navigation.megamenu.close', 'Close menu')}
|
||||
name="times"
|
||||
onClick={onClose}
|
||||
size="xl"
|
||||
variant="secondary"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
MegaMenuHeader.displayName = 'MegaMenuHeader';
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
dockMenuButton: css({
|
||||
display: 'none',
|
||||
|
||||
[theme.breakpoints.up('xl')]: {
|
||||
display: 'inline-flex',
|
||||
},
|
||||
}),
|
||||
header: css({
|
||||
alignItems: 'center',
|
||||
borderBottom: `1px solid ${theme.colors.border.weak}`,
|
||||
display: 'flex',
|
||||
gap: theme.spacing(1),
|
||||
justifyContent: 'space-between',
|
||||
padding: theme.spacing(0, 1, 0, 0.5),
|
||||
height: TOP_BAR_LEVEL_HEIGHT,
|
||||
minHeight: TOP_BAR_LEVEL_HEIGHT,
|
||||
}),
|
||||
img: css({
|
||||
alignSelf: 'center',
|
||||
height: theme.spacing(3),
|
||||
width: theme.spacing(3),
|
||||
}),
|
||||
mobileCloseButton: css({
|
||||
[theme.breakpoints.up('md')]: {
|
||||
display: 'none',
|
||||
},
|
||||
}),
|
||||
});
|
@ -5,6 +5,7 @@ import { memo } from 'react';
|
||||
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
|
||||
import { Dropdown, Icon, ToolbarButton, useStyles2 } from '@grafana/ui';
|
||||
import { config } from 'app/core/config';
|
||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { HOME_NAV_ID } from 'app/core/reducers/navModel';
|
||||
import { ScopesSelector } from 'app/features/scopes';
|
||||
@ -37,7 +38,10 @@ export const SingleTopBar = memo(function SingleTopBar({
|
||||
pageNav,
|
||||
sectionNav,
|
||||
}: Props) {
|
||||
const styles = useStyles2(getStyles);
|
||||
const { chrome } = useGrafana();
|
||||
const state = chrome.useState();
|
||||
const menuDockedAndOpen = !state.chromeless && state.megaMenuDocked && state.megaMenuOpen;
|
||||
const styles = useStyles2(getStyles, menuDockedAndOpen);
|
||||
const navIndex = useSelector((state) => state.navIndex);
|
||||
|
||||
const helpNode = cloneDeep(navIndex['help']);
|
||||
@ -49,9 +53,11 @@ export const SingleTopBar = memo(function SingleTopBar({
|
||||
return (
|
||||
<div className={styles.layout}>
|
||||
<TopSearchBarSection>
|
||||
<ToolbarButton narrow onClick={onToggleMegaMenu}>
|
||||
<Branding.MenuLogo className={styles.img} />
|
||||
</ToolbarButton>
|
||||
{!menuDockedAndOpen && (
|
||||
<ToolbarButton narrow onClick={onToggleMegaMenu}>
|
||||
<Branding.MenuLogo className={styles.img} />
|
||||
</ToolbarButton>
|
||||
)}
|
||||
<Breadcrumbs breadcrumbs={breadcrumbs} className={styles.breadcrumbsWrapper} />
|
||||
<OrganizationSwitcher />
|
||||
<ScopesSelector />
|
||||
@ -85,13 +91,14 @@ export const SingleTopBar = memo(function SingleTopBar({
|
||||
);
|
||||
});
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
const getStyles = (theme: GrafanaTheme2, menuDockedAndOpen: boolean) => ({
|
||||
layout: css({
|
||||
height: TOP_BAR_LEVEL_HEIGHT,
|
||||
display: 'flex',
|
||||
gap: theme.spacing(1),
|
||||
alignItems: 'center',
|
||||
padding: theme.spacing(0, 1),
|
||||
paddingLeft: menuDockedAndOpen ? theme.spacing(3.5) : theme.spacing(0.5),
|
||||
borderBottom: `1px solid ${theme.colors.border.weak}`,
|
||||
justifyContent: 'space-between',
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user