mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore(Navigation): Rename SideMenu -> NavBar (#39483)
This commit is contained in:
@@ -9,7 +9,7 @@ import { getAppRoutes } from 'app/routes/routes';
|
||||
import { ConfigContext, ThemeProvider } from './core/utils/ConfigProvider';
|
||||
import { RouteDescriptor } from './core/navigation/types';
|
||||
import { contextSrv } from './core/services/context_srv';
|
||||
import { SideMenu } from './core/components/sidemenu/SideMenu';
|
||||
import { NavBar } from './core/components/NavBar/NavBar';
|
||||
import { GrafanaRoute } from './core/navigation/GrafanaRoute';
|
||||
import { AppNotificationList } from './core/components/AppNotifications/AppNotificationList';
|
||||
import { SearchWrapper } from 'app/features/search';
|
||||
@@ -96,7 +96,7 @@ export class AppWrapper extends React.Component<AppWrapperProps, AppWrapperState
|
||||
<GlobalStyles />
|
||||
<div className="grafana-app">
|
||||
<Router history={locationService.getHistory()}>
|
||||
<SideMenu />
|
||||
<NavBar />
|
||||
<main className="main-view">
|
||||
<div
|
||||
ref={this.container}
|
||||
|
@@ -11,7 +11,7 @@ import config from '../../config';
|
||||
import { OrgSwitcher } from '../OrgSwitcher';
|
||||
import { getFooterLinks } from '../Footer/Footer';
|
||||
import { HelpModal } from '../help/HelpModal';
|
||||
import SideMenuItem from './SideMenuItem';
|
||||
import NavBarItem from './NavBarItem';
|
||||
import { getForcedLoginUrl, isLinkActive, isSearchActive } from './utils';
|
||||
|
||||
export default function BottomSection() {
|
||||
@@ -45,9 +45,9 @@ export default function BottomSection() {
|
||||
return (
|
||||
<div data-testid="bottom-section-items" className={styles.container}>
|
||||
{!isSignedIn && (
|
||||
<SideMenuItem label="Sign In" target="_self" url={forcedLoginUrl}>
|
||||
<NavBarItem label="Sign In" target="_self" url={forcedLoginUrl}>
|
||||
<Icon name="signout" size="xl" />
|
||||
</SideMenuItem>
|
||||
</NavBarItem>
|
||||
)}
|
||||
{bottomNav.map((link, index) => {
|
||||
let menuItems = link.children || [];
|
||||
@@ -75,7 +75,7 @@ export default function BottomSection() {
|
||||
}
|
||||
|
||||
return (
|
||||
<SideMenuItem
|
||||
<NavBarItem
|
||||
key={`${link.url}-${index}`}
|
||||
isActive={!isSearchActive(location) && activeItemId === link.id}
|
||||
label={link.text}
|
||||
@@ -88,7 +88,7 @@ export default function BottomSection() {
|
||||
>
|
||||
{link.icon && <Icon name={link.icon as IconName} size="xl" />}
|
||||
{link.img && <img src={link.img} alt={`${link.text} logo`} />}
|
||||
</SideMenuItem>
|
||||
</NavBarItem>
|
||||
);
|
||||
})}
|
||||
{showSwitcherModal && <OrgSwitcher onDismiss={toggleSwitcherModal} />}
|
@@ -1,15 +1,15 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import DropDownChild from './DropDownChild';
|
||||
import DropdownChild from './DropdownChild';
|
||||
|
||||
describe('DropDownChild', () => {
|
||||
describe('DropdownChild', () => {
|
||||
const mockText = 'MyChildItem';
|
||||
const mockUrl = '/route';
|
||||
const mockIcon = 'home-alt';
|
||||
|
||||
it('displays the text', () => {
|
||||
render(<DropDownChild text={mockText} />);
|
||||
render(<DropdownChild text={mockText} />);
|
||||
const text = screen.getByText(mockText);
|
||||
expect(text).toBeInTheDocument();
|
||||
});
|
||||
@@ -17,7 +17,7 @@ describe('DropDownChild', () => {
|
||||
it('attaches the url to the text if provided', () => {
|
||||
render(
|
||||
<BrowserRouter>
|
||||
<DropDownChild text={mockText} url={mockUrl} />
|
||||
<DropdownChild text={mockText} url={mockUrl} />
|
||||
</BrowserRouter>
|
||||
);
|
||||
const link = screen.getByRole('link', { name: mockText });
|
||||
@@ -26,13 +26,13 @@ describe('DropDownChild', () => {
|
||||
});
|
||||
|
||||
it('displays an icon if a valid icon is provided', () => {
|
||||
render(<DropDownChild text={mockText} icon={mockIcon} />);
|
||||
render(<DropdownChild text={mockText} icon={mockIcon} />);
|
||||
const icon = screen.getByTestId('dropdown-child-icon');
|
||||
expect(icon).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('displays a divider instead when isDivider is true', () => {
|
||||
render(<DropDownChild text={mockText} icon={mockIcon} url={mockUrl} isDivider />);
|
||||
render(<DropdownChild text={mockText} icon={mockIcon} url={mockUrl} isDivider />);
|
||||
|
||||
// Check the divider is shown
|
||||
const divider = screen.getByTestId('dropdown-child-divider');
|
@@ -12,7 +12,7 @@ export interface Props {
|
||||
url?: string;
|
||||
}
|
||||
|
||||
const DropDownChild = ({ isDivider = false, icon, onClick, target, text, url }: Props) => {
|
||||
const DropdownChild = ({ isDivider = false, icon, onClick, target, text, url }: Props) => {
|
||||
const theme = useTheme2();
|
||||
const styles = getStyles(theme);
|
||||
|
||||
@@ -44,7 +44,7 @@ const DropDownChild = ({ isDivider = false, icon, onClick, target, text, url }:
|
||||
return isDivider ? <li data-testid="dropdown-child-divider" className="divider" /> : <li>{element}</li>;
|
||||
};
|
||||
|
||||
export default DropDownChild;
|
||||
export default DropdownChild;
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
element: css`
|
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { SideMenu } from './SideMenu';
|
||||
import { NavBar } from './NavBar';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
@@ -23,7 +23,7 @@ const setup = () => {
|
||||
return render(
|
||||
<Provider store={store}>
|
||||
<Router history={locationService.getHistory()}>
|
||||
<SideMenu />
|
||||
<NavBar />
|
||||
</Router>
|
||||
</Provider>
|
||||
);
|
@@ -12,14 +12,14 @@ import BottomSection from './BottomSection';
|
||||
|
||||
const homeUrl = config.appSubUrl || '/';
|
||||
|
||||
export const SideMenu: FC = React.memo(() => {
|
||||
export const NavBar: FC = React.memo(() => {
|
||||
const theme = useTheme2();
|
||||
const styles = getStyles(theme);
|
||||
const location = useLocation();
|
||||
const query = new URLSearchParams(location.search);
|
||||
const kiosk = query.get('kiosk') as KioskMode;
|
||||
|
||||
const toggleSideMenuSmallBreakpoint = useCallback(() => {
|
||||
const toggleNavBarSmallBreakpoint = useCallback(() => {
|
||||
appEvents.emit(CoreEvents.toggleSidemenuMobile);
|
||||
}, []);
|
||||
|
||||
@@ -32,7 +32,7 @@ export const SideMenu: FC = React.memo(() => {
|
||||
<a href={homeUrl} className={styles.homeLogo}>
|
||||
<Branding.MenuLogo />
|
||||
</a>
|
||||
<div className={styles.mobileSidemenuLogo} onClick={toggleSideMenuSmallBreakpoint} key="hamburger">
|
||||
<div className={styles.mobileSidemenuLogo} onClick={toggleNavBarSmallBreakpoint} key="hamburger">
|
||||
<Icon name="bars" size="xl" />
|
||||
<span className={styles.closeButton}>
|
||||
<Icon name="times" />
|
||||
@@ -45,7 +45,7 @@ export const SideMenu: FC = React.memo(() => {
|
||||
);
|
||||
});
|
||||
|
||||
SideMenu.displayName = 'SideMenu';
|
||||
NavBar.displayName = 'NavBar';
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
sidemenu: css`
|
@@ -2,9 +2,9 @@ import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import SideMenuDropDown from './SideMenuDropDown';
|
||||
import NavBarDropdown from './NavBarDropdown';
|
||||
|
||||
describe('SideMenuDropDown', () => {
|
||||
describe('NavBarDropdown', () => {
|
||||
const mockHeaderText = 'MyHeaderText';
|
||||
const mockHeaderUrl = '/route';
|
||||
const mockOnHeaderClick = jest.fn();
|
||||
@@ -18,7 +18,7 @@ describe('SideMenuDropDown', () => {
|
||||
];
|
||||
|
||||
it('displays the header text', () => {
|
||||
render(<SideMenuDropDown headerText={mockHeaderText} />);
|
||||
render(<NavBarDropdown headerText={mockHeaderText} />);
|
||||
const text = screen.getByText(mockHeaderText);
|
||||
expect(text).toBeInTheDocument();
|
||||
});
|
||||
@@ -26,7 +26,7 @@ describe('SideMenuDropDown', () => {
|
||||
it('attaches the header url to the header text if provided', () => {
|
||||
render(
|
||||
<BrowserRouter>
|
||||
<SideMenuDropDown headerText={mockHeaderText} headerUrl={mockHeaderUrl} />
|
||||
<NavBarDropdown headerText={mockHeaderText} headerUrl={mockHeaderUrl} />
|
||||
</BrowserRouter>
|
||||
);
|
||||
const link = screen.getByRole('link', { name: mockHeaderText });
|
||||
@@ -35,7 +35,7 @@ describe('SideMenuDropDown', () => {
|
||||
});
|
||||
|
||||
it('calls the onHeaderClick function when the header is clicked', () => {
|
||||
render(<SideMenuDropDown headerText={mockHeaderText} onHeaderClick={mockOnHeaderClick} />);
|
||||
render(<NavBarDropdown headerText={mockHeaderText} onHeaderClick={mockOnHeaderClick} />);
|
||||
const text = screen.getByText(mockHeaderText);
|
||||
expect(text).toBeInTheDocument();
|
||||
userEvent.click(text);
|
||||
@@ -43,7 +43,7 @@ describe('SideMenuDropDown', () => {
|
||||
});
|
||||
|
||||
it('displays the items', () => {
|
||||
render(<SideMenuDropDown headerText={mockHeaderText} items={mockItems} />);
|
||||
render(<NavBarDropdown headerText={mockHeaderText} items={mockItems} />);
|
||||
mockItems.forEach(({ text }) => {
|
||||
const childItem = screen.getByText(text);
|
||||
expect(childItem).toBeInTheDocument();
|
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { css } from '@emotion/css';
|
||||
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
|
||||
import { IconName, Link, useTheme2 } from '@grafana/ui';
|
||||
import DropDownChild from './DropDownChild';
|
||||
import DropdownChild from './DropdownChild';
|
||||
|
||||
interface Props {
|
||||
headerTarget?: HTMLAnchorElement['target'];
|
||||
@@ -14,7 +14,7 @@ interface Props {
|
||||
subtitleText?: string;
|
||||
}
|
||||
|
||||
const SideMenuDropDown = ({
|
||||
const NavBarDropdown = ({
|
||||
headerTarget,
|
||||
headerText,
|
||||
headerUrl,
|
||||
@@ -50,7 +50,7 @@ const SideMenuDropDown = ({
|
||||
{items
|
||||
.filter((item) => !item.hideFromMenu)
|
||||
.map((child, index) => (
|
||||
<DropDownChild
|
||||
<DropdownChild
|
||||
key={`${child.url}-${index}`}
|
||||
isDivider={child.divider}
|
||||
icon={child.icon as IconName}
|
||||
@@ -65,7 +65,7 @@ const SideMenuDropDown = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default SideMenuDropDown;
|
||||
export default NavBarDropdown;
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2, reverseDirection: Props['reverseDirection']) => ({
|
||||
header: css`
|
@@ -2,16 +2,16 @@ import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import SideMenuItem from './SideMenuItem';
|
||||
import NavBarItem from './NavBarItem';
|
||||
|
||||
describe('SideMenuItem', () => {
|
||||
describe('NavBarItem', () => {
|
||||
it('renders the children', () => {
|
||||
const mockLabel = 'Hello';
|
||||
render(
|
||||
<BrowserRouter>
|
||||
<SideMenuItem label={mockLabel}>
|
||||
<NavBarItem label={mockLabel}>
|
||||
<div data-testid="mockChild" />
|
||||
</SideMenuItem>
|
||||
</NavBarItem>
|
||||
</BrowserRouter>
|
||||
);
|
||||
|
||||
@@ -24,9 +24,9 @@ describe('SideMenuItem', () => {
|
||||
const mockUrl = '/route';
|
||||
render(
|
||||
<BrowserRouter>
|
||||
<SideMenuItem label={mockLabel} url={mockUrl}>
|
||||
<NavBarItem label={mockLabel} url={mockUrl}>
|
||||
<div data-testid="mockChild" />
|
||||
</SideMenuItem>
|
||||
</NavBarItem>
|
||||
</BrowserRouter>
|
||||
);
|
||||
|
||||
@@ -41,9 +41,9 @@ describe('SideMenuItem', () => {
|
||||
const mockOnClick = jest.fn();
|
||||
render(
|
||||
<BrowserRouter>
|
||||
<SideMenuItem label={mockLabel} onClick={mockOnClick}>
|
||||
<NavBarItem label={mockLabel} onClick={mockOnClick}>
|
||||
<div data-testid="mockChild" />
|
||||
</SideMenuItem>
|
||||
</NavBarItem>
|
||||
</BrowserRouter>
|
||||
);
|
||||
|
@@ -2,7 +2,7 @@ import React, { ReactNode } from 'react';
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
|
||||
import { Link, useTheme2 } from '@grafana/ui';
|
||||
import SideMenuDropDown from './SideMenuDropDown';
|
||||
import NavBarDropdown from './NavBarDropdown';
|
||||
|
||||
export interface Props {
|
||||
isActive?: boolean;
|
||||
@@ -16,7 +16,7 @@ export interface Props {
|
||||
url?: string;
|
||||
}
|
||||
|
||||
const SideMenuItem = ({
|
||||
const NavBarItem = ({
|
||||
isActive = false,
|
||||
children,
|
||||
label,
|
||||
@@ -58,7 +58,7 @@ const SideMenuItem = ({
|
||||
return (
|
||||
<div className={cx(styles.container, 'dropdown', { dropup: reverseMenuDirection })}>
|
||||
{element}
|
||||
<SideMenuDropDown
|
||||
<NavBarDropdown
|
||||
headerTarget={target}
|
||||
headerText={label}
|
||||
headerUrl={url}
|
||||
@@ -71,7 +71,7 @@ const SideMenuItem = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default SideMenuItem;
|
||||
export default NavBarItem;
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2, isActive: Props['isActive']) => ({
|
||||
container: css`
|
@@ -7,7 +7,7 @@ import { locationService } from '@grafana/runtime';
|
||||
import { Icon, IconName, useTheme2 } from '@grafana/ui';
|
||||
import config from '../../config';
|
||||
import { isLinkActive, isSearchActive } from './utils';
|
||||
import SideMenuItem from './SideMenuItem';
|
||||
import NavBarItem from './NavBarItem';
|
||||
|
||||
const TopSection = () => {
|
||||
const location = useLocation();
|
||||
@@ -23,12 +23,12 @@ const TopSection = () => {
|
||||
|
||||
return (
|
||||
<div data-testid="top-section-items" className={styles.container}>
|
||||
<SideMenuItem isActive={isSearchActive(location)} label="Search dashboards" onClick={onOpenSearch}>
|
||||
<NavBarItem isActive={isSearchActive(location)} label="Search dashboards" onClick={onOpenSearch}>
|
||||
<Icon name="search" size="xl" />
|
||||
</SideMenuItem>
|
||||
</NavBarItem>
|
||||
{mainLinks.map((link, index) => {
|
||||
return (
|
||||
<SideMenuItem
|
||||
<NavBarItem
|
||||
key={`${link.id}-${index}`}
|
||||
isActive={!isSearchActive(location) && activeItemId === link.id}
|
||||
label={link.text}
|
||||
@@ -38,7 +38,7 @@ const TopSection = () => {
|
||||
>
|
||||
{link.icon && <Icon name={link.icon as IconName} size="xl" />}
|
||||
{link.img && <img src={link.img} alt={`${link.text} logo`} />}
|
||||
</SideMenuItem>
|
||||
</NavBarItem>
|
||||
);
|
||||
})}
|
||||
</div>
|
Reference in New Issue
Block a user