DataLinks: Fix onClick functionality (#94815)

* fix: add onclick functionality back to DataLinks in VizPanelFooter

---------

Co-authored-by: Adela Almasan <adela.almasan@grafana.com>
Co-authored-by: Matias Chomicki <matyax@gmail.com>
This commit is contained in:
Galen Kistler 2024-10-17 12:07:22 -05:00 committed by GitHub
parent c062389f66
commit 5fe5e8a5a6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 62 additions and 15 deletions

View File

@ -28,7 +28,7 @@ export function DataLinkButton({ link, buttonProps }: DataLinkButtonProps) {
}
>
<Button
icon={link.target === '_blank' ? 'external-link-alt' : undefined}
icon={link.target === '_blank' ? 'external-link-alt' : 'link'}
variant="primary"
size="sm"
{...buttonProps}

View File

@ -1,4 +1,5 @@
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router-dom-v5-compat';
import { GrafanaConfig, locationUtil } from '@grafana/data';
@ -48,4 +49,17 @@ describe('TextLink', () => {
);
expect(screen.getByRole('link')).toHaveAttribute('href', '/after-sub-url');
});
it('should fire onclick', async () => {
const onClick = jest.fn();
render(
<MemoryRouter>
<TextLink onClick={onClick} href={link}>
Link to Grafana
</TextLink>
</MemoryRouter>
);
await userEvent.click(screen.getByRole('link'));
expect(onClick).toHaveBeenCalled();
});
});

View File

@ -0,0 +1,35 @@
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router-dom-v5-compat';
import { Field, FieldType, LinkModel } from '@grafana/data';
import { VizTooltipFooter } from './VizTooltipFooter';
describe('VizTooltipFooter', () => {
it('should fire onclick', async () => {
const onClick = jest.fn();
const field: Field = {
name: '',
type: FieldType.string,
values: [],
config: {},
};
const link: LinkModel<Field> = {
href: '#',
onClick,
title: '',
origin: field,
target: undefined,
};
render(
<MemoryRouter>
<VizTooltipFooter dataLinks={[link]} />
</MemoryRouter>
);
await userEvent.click(screen.getByRole('link'));
expect(onClick).toHaveBeenCalled();
});
});

View File

@ -2,7 +2,7 @@ import { css } from '@emotion/css';
import { ActionModel, Field, GrafanaTheme2, LinkModel } from '@grafana/data';
import { Button, Stack, TextLink } from '..';
import { Button, DataLinkButton, Stack } from '..';
import { useStyles2 } from '../../themes';
import { ActionButton } from '../Actions/ActionButton';
@ -14,20 +14,11 @@ interface VizTooltipFooterProps {
export const ADD_ANNOTATION_ID = 'add-annotation-button';
const renderDataLinks = (dataLinks: LinkModel[]) => {
const renderDataLinks = (dataLinks: LinkModel[], styles: ReturnType<typeof getStyles>) => {
return (
<Stack direction="column" justifyContent="flex-start">
<Stack direction="column" justifyContent="flex-start" gap={0.5}>
{dataLinks.map((link, i) => (
<TextLink
key={i}
href={link.href}
external={link.target === '_blank'}
weight={'medium'}
inline={false}
variant={'bodySmall'}
>
{link.title}
</TextLink>
<DataLinkButton link={link} key={i} buttonProps={{ className: styles.dataLinkButton, fill: 'text' }} />
))}
</Stack>
);
@ -48,7 +39,7 @@ export const VizTooltipFooter = ({ dataLinks, actions, annotate }: VizTooltipFoo
return (
<div className={styles.wrapper}>
{dataLinks.length > 0 && <div className={styles.dataLinks}>{renderDataLinks(dataLinks)}</div>}
{dataLinks.length > 0 && <div className={styles.dataLinks}>{renderDataLinks(dataLinks, styles)}</div>}
{actions && actions.length > 0 && <div className={styles.dataLinks}>{renderActions(actions)}</div>}
{annotate != null && (
<div className={styles.addAnnotations}>
@ -76,4 +67,11 @@ const getStyles = (theme: GrafanaTheme2) => ({
borderTop: `1px solid ${theme.colors.border.medium}`,
padding: theme.spacing(1),
}),
dataLinkButton: css({
cursor: 'pointer',
'&:hover': {
textDecoration: 'underline',
background: 'none',
},
}),
});