mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Sidemenu: Refactor DropDownChild
(#38509)
* DropDownChild: Refactor DropDownChild to be more component-like * Rewrite tests in RTL * Let's not do this just yet...
This commit is contained in:
@@ -1,35 +1,48 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import DropDownChild from './DropDownChild';
|
||||
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props = Object.assign(
|
||||
{
|
||||
child: {
|
||||
divider: true,
|
||||
},
|
||||
},
|
||||
propOverrides
|
||||
);
|
||||
describe('DropDownChild', () => {
|
||||
const mockText = 'MyChildItem';
|
||||
const mockUrl = '/route';
|
||||
const mockIcon = 'home-alt';
|
||||
|
||||
return shallow(<DropDownChild {...props} />);
|
||||
};
|
||||
|
||||
describe('Render', () => {
|
||||
it('should render component', () => {
|
||||
const wrapper = setup();
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
it('displays the text', () => {
|
||||
render(<DropDownChild text={mockText} />);
|
||||
const text = screen.getByText(mockText);
|
||||
expect(text).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render icon if exists', () => {
|
||||
const wrapper = setup({
|
||||
child: {
|
||||
divider: false,
|
||||
icon: 'icon-test',
|
||||
},
|
||||
});
|
||||
it('attaches the link to the text if provided', () => {
|
||||
render(
|
||||
<BrowserRouter>
|
||||
<DropDownChild text={mockText} url={mockUrl} />
|
||||
</BrowserRouter>
|
||||
);
|
||||
const link = screen.getByRole('link', { name: mockText });
|
||||
expect(link).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
it('displays an icon if a valid icon is provided', () => {
|
||||
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 />);
|
||||
|
||||
// Check the divider is shown
|
||||
const divider = screen.getByTestId('dropdown-child-divider');
|
||||
expect(divider).toBeInTheDocument();
|
||||
|
||||
// Check nothing else is rendered
|
||||
const text = screen.queryByText(mockText);
|
||||
const icon = screen.queryByTestId('dropdown-child-icon');
|
||||
const link = screen.queryByRole('link', { name: mockText });
|
||||
expect(text).not.toBeInTheDocument();
|
||||
expect(icon).not.toBeInTheDocument();
|
||||
expect(link).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
@@ -1,29 +1,30 @@
|
||||
import React, { FC } from 'react';
|
||||
import React from 'react';
|
||||
import { css } from '@emotion/css';
|
||||
import { Icon, IconName, Link, useTheme } from '@grafana/ui';
|
||||
import { Icon, IconName, Link, useTheme2 } from '@grafana/ui';
|
||||
|
||||
export interface Props {
|
||||
child: any;
|
||||
isDivider?: boolean;
|
||||
icon?: IconName;
|
||||
text: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
const DropDownChild: FC<Props> = (props) => {
|
||||
const { child } = props;
|
||||
const listItemClassName = child.divider ? 'divider' : '';
|
||||
const theme = useTheme();
|
||||
const DropDownChild = ({ isDivider = false, icon, text, url }: Props) => {
|
||||
const theme = useTheme2();
|
||||
const iconClassName = css`
|
||||
margin-right: ${theme.spacing.sm};
|
||||
margin-right: ${theme.spacing(1)};
|
||||
`;
|
||||
|
||||
const linkContent = (
|
||||
<>
|
||||
{child.icon && <Icon name={child.icon as IconName} className={iconClassName} />}
|
||||
{child.text}
|
||||
{icon && <Icon data-testid="dropdown-child-icon" name={icon} className={iconClassName} />}
|
||||
{text}
|
||||
</>
|
||||
);
|
||||
|
||||
const anchor = child.url ? <Link href={child.url}>{linkContent}</Link> : <a>{linkContent}</a>;
|
||||
const anchor = url ? <Link href={url}>{linkContent}</Link> : <a>{linkContent}</a>;
|
||||
|
||||
return <li className={listItemClassName}>{anchor}</li>;
|
||||
return isDivider ? <li data-testid="dropdown-child-divider" className="divider" /> : <li>{anchor}</li>;
|
||||
};
|
||||
|
||||
export default DropDownChild;
|
||||
|
@@ -2,7 +2,7 @@ import React, { FC } from 'react';
|
||||
import { filter } from 'lodash';
|
||||
import DropDownChild from './DropDownChild';
|
||||
import { NavModelItem } from '@grafana/data';
|
||||
import { Link } from '@grafana/ui';
|
||||
import { IconName, Link } from '@grafana/ui';
|
||||
|
||||
interface Props {
|
||||
link: NavModelItem;
|
||||
@@ -30,9 +30,15 @@ const SideMenuDropDown: FC<Props> = (props) => {
|
||||
return (
|
||||
<ul className="dropdown-menu dropdown-menu--sidemenu" role="menu">
|
||||
<li className="side-menu-header">{anchor}</li>
|
||||
{childrenLinks.map((child, index) => {
|
||||
return <DropDownChild child={child} key={`${child.url}-${index}`} />;
|
||||
})}
|
||||
{childrenLinks.map((child, index) => (
|
||||
<DropDownChild
|
||||
key={`${child.url}-${index}`}
|
||||
isDivider={child.divider}
|
||||
icon={child.icon as IconName}
|
||||
text={child.text}
|
||||
url={child.url}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
@@ -1,22 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Render should render component 1`] = `
|
||||
<li
|
||||
className="divider"
|
||||
>
|
||||
<a />
|
||||
</li>
|
||||
`;
|
||||
|
||||
exports[`Render should render icon if exists 1`] = `
|
||||
<li
|
||||
className=""
|
||||
>
|
||||
<a>
|
||||
<Icon
|
||||
className="css-290ig"
|
||||
name="icon-test"
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
`;
|
@@ -19,21 +19,9 @@ exports[`Render should not render hideFromMenu children 1`] = `
|
||||
</a>
|
||||
</li>
|
||||
<DropDownChild
|
||||
child={
|
||||
Object {
|
||||
"hideFromMenu": false,
|
||||
"id": 1,
|
||||
}
|
||||
}
|
||||
key="undefined-0"
|
||||
/>
|
||||
<DropDownChild
|
||||
child={
|
||||
Object {
|
||||
"hideFromMenu": false,
|
||||
"id": 3,
|
||||
}
|
||||
}
|
||||
key="undefined-1"
|
||||
/>
|
||||
</ul>
|
||||
@@ -58,27 +46,12 @@ exports[`Render should render children 1`] = `
|
||||
</a>
|
||||
</li>
|
||||
<DropDownChild
|
||||
child={
|
||||
Object {
|
||||
"id": 1,
|
||||
}
|
||||
}
|
||||
key="undefined-0"
|
||||
/>
|
||||
<DropDownChild
|
||||
child={
|
||||
Object {
|
||||
"id": 2,
|
||||
}
|
||||
}
|
||||
key="undefined-1"
|
||||
/>
|
||||
<DropDownChild
|
||||
child={
|
||||
Object {
|
||||
"id": 3,
|
||||
}
|
||||
}
|
||||
key="undefined-2"
|
||||
/>
|
||||
</ul>
|
||||
|
Reference in New Issue
Block a user