Alerting: Refactor ActionIcon to use our normal Button and LinkButton components (#45227)

* Alerting: Refactor ActionIcon to use our normal Button and LinkButton components

* Fixed test

* Fixed test
This commit is contained in:
Torkel Ödegaard 2022-02-11 10:12:26 +01:00 committed by GitHub
parent c6b3698922
commit cc49537965
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 49 deletions

View File

@ -24,6 +24,7 @@ import store from 'app/core/store';
import { contextSrv } from 'app/core/services/context_srv'; import { contextSrv } from 'app/core/services/context_srv';
import { selectOptionInTest } from '@grafana/ui'; import { selectOptionInTest } from '@grafana/ui';
import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from 'app/plugins/datasource/alertmanager/types'; import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from 'app/plugins/datasource/alertmanager/types';
import { interceptLinkClicks } from 'app/core/navigation/patch/interceptLinkClicks';
jest.mock('./api/alertmanager'); jest.mock('./api/alertmanager');
jest.mock('./api/grafana'); jest.mock('./api/grafana');
@ -116,6 +117,8 @@ const clickSelectOption = async (selectElement: HTMLElement, optionText: string)
await selectOptionInTest(selectElement, optionText); await selectOptionInTest(selectElement, optionText);
}; };
document.addEventListener('click', interceptLinkClicks);
describe('Receivers', () => { describe('Receivers', () => {
beforeEach(() => { beforeEach(() => {
jest.resetAllMocks(); jest.resetAllMocks();
@ -404,11 +407,12 @@ describe('Receivers', () => {
const receiverRows = receiversTable.querySelectorAll<HTMLTableRowElement>('tbody tr'); const receiverRows = receiversTable.querySelectorAll<HTMLTableRowElement>('tbody tr');
expect(receiverRows[0]).toHaveTextContent('cloud-receiver'); expect(receiverRows[0]).toHaveTextContent('cloud-receiver');
expect(byTestId('edit').query(receiverRows[0])).not.toBeInTheDocument(); expect(byTestId('edit').query(receiverRows[0])).not.toBeInTheDocument();
await userEvent.click(byTestId('view').get(receiverRows[0])); userEvent.click(byTestId('view').get(receiverRows[0]));
// check that form is open // check that form is open
await byRole('heading', { name: /contact point/i }).find(); await byRole('heading', { name: /contact point/i }).find();
expect(locationService.getLocation().pathname).toEqual('/alerting/notifications/receivers/cloud-receiver/edit'); expect(locationService.getLocation().pathname).toEqual('/alerting/notifications/receivers/cloud-receiver/edit');
const channelForms = ui.channelFormContainer.queryAll(); const channelForms = ui.channelFormContainer.queryAll();
expect(channelForms).toHaveLength(2); expect(channelForms).toHaveLength(2);

View File

@ -1,18 +1,15 @@
import { Icon, IconName, useStyles, Tooltip } from '@grafana/ui'; import { IconName, Tooltip, LinkButton, Button } from '@grafana/ui';
import { PopoverContent, TooltipPlacement } from '@grafana/ui/src/components/Tooltip'; import { PopoverContent, TooltipPlacement } from '@grafana/ui/src/components/Tooltip';
import React, { FC } from 'react'; import React, { FC } from 'react';
import { css, cx } from '@emotion/css';
import { Link } from 'react-router-dom';
interface Props { interface Props {
tooltip: PopoverContent; tooltip: PopoverContent;
icon: IconName; icon: IconName;
className?: string; className?: string;
tooltipPlacement?: TooltipPlacement; tooltipPlacement?: TooltipPlacement;
to?: string; to?: string;
target?: string; target?: string;
onClick?: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void; onClick?: () => void;
'data-testid'?: string; 'data-testid'?: string;
} }
@ -27,53 +24,33 @@ export const ActionIcon: FC<Props> = ({
...rest ...rest
}) => { }) => {
const ariaLabel = typeof tooltip === 'string' ? tooltip : undefined; const ariaLabel = typeof tooltip === 'string' ? tooltip : undefined;
const iconEl = (
<Icon
role="button"
className={cx(useStyles(getStyle), className)}
onClick={onClick}
name={icon}
{...rest}
aria-label={ariaLabel}
/>
);
return ( return (
<Tooltip content={tooltip} placement={tooltipPlacement}> <Tooltip content={tooltip} placement={tooltipPlacement}>
{to ? ( {to ? (
<GoTo url={to} label={ariaLabel} target={target}> <LinkButton
{iconEl} variant="secondary"
</GoTo> fill="text"
icon={icon}
href={to}
size="sm"
target={target}
{...rest}
aria-label={ariaLabel}
/>
) : ( ) : (
iconEl <Button
className={className}
variant="secondary"
fill="text"
size="sm"
icon={icon}
type="button"
onClick={onClick}
{...rest}
aria-label={ariaLabel}
/>
)} )}
</Tooltip> </Tooltip>
); );
}; };
interface GoToProps {
url: string;
label?: string;
target?: string;
children?: React.ReactNode;
}
const GoTo = React.forwardRef<HTMLAnchorElement, GoToProps>(({ url, label, target, children }, ref) => {
const absoluteUrl = url?.startsWith('http');
return absoluteUrl ? (
<a ref={ref} aria-label={label} href={url} target={target}>
{children}
</a>
) : (
<Link ref={ref} aria-label={label} to={url} target={target}>
{children}
</Link>
);
});
GoTo.displayName = 'GoTo';
export const getStyle = () => css`
cursor: pointer;
`;

View File

@ -191,7 +191,7 @@ export const getStyles = (theme: GrafanaTheme2) => ({
`, `,
actionIcons: css` actionIcons: css`
& > * + * { & > * + * {
margin-left: ${theme.spacing(1)}; margin-left: ${theme.spacing(0.5)};
} }
`, `,
rulesTable: css` rulesTable: css`

View File

@ -32,7 +32,7 @@ export const getAlertTableStyles = (theme: GrafanaTheme2) => ({
white-space: nowrap; white-space: nowrap;
& > * + * { & > * + * {
margin-left: ${theme.spacing(1)}; margin-left: ${theme.spacing(0.5)};
} }
`, `,
}); });