mirror of
https://github.com/grafana/grafana.git
synced 2025-01-13 09:32:12 -06:00
DataLinks: Bring back single click links for Stat, Gauge and BarGauge panel (#31692)
* Bring back clickable Stat, Gauge and BarGauge panels * Demo dashboard * Add DataLinksContextMenu tests * Only use new UI for data links, revert panel links logic
This commit is contained in:
parent
bbee7da3e0
commit
fdc6f2cc6f
1194
devenv/dev-dashboards/panel-common/linked-viz.json
Normal file
1194
devenv/dev-dashboards/panel-common/linked-viz.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -181,4 +181,7 @@ export const Components = {
|
||||
CallToActionCard: {
|
||||
button: (name: string) => `Call to action button ${name}`,
|
||||
},
|
||||
DataLinksContextMenu: {
|
||||
singleLink: 'Data link',
|
||||
},
|
||||
};
|
||||
|
@ -0,0 +1,77 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { DataLinksContextMenu } from './DataLinksContextMenu';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
const fakeAriaLabel = 'fake aria label';
|
||||
describe('DataLinksContextMenu', () => {
|
||||
it('renders context menu when there are more than one data links', () => {
|
||||
render(
|
||||
<DataLinksContextMenu
|
||||
links={() => [
|
||||
{
|
||||
href: '/link1',
|
||||
title: 'Link1',
|
||||
target: '_blank',
|
||||
origin: {},
|
||||
},
|
||||
{
|
||||
href: '/link2',
|
||||
title: 'Link2',
|
||||
target: '_blank',
|
||||
origin: {},
|
||||
},
|
||||
]}
|
||||
config={{
|
||||
links: [
|
||||
{
|
||||
title: 'Link1',
|
||||
url: '/link1',
|
||||
},
|
||||
{
|
||||
title: 'Link2',
|
||||
url: '/link2',
|
||||
},
|
||||
],
|
||||
}}
|
||||
>
|
||||
{() => {
|
||||
return <div aria-label="fake aria label" />;
|
||||
}}
|
||||
</DataLinksContextMenu>
|
||||
);
|
||||
|
||||
expect(screen.getByLabelText(fakeAriaLabel)).toBeInTheDocument();
|
||||
expect(screen.queryAllByLabelText(selectors.components.DataLinksContextMenu.singleLink)).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('renders link when there is a single data link', () => {
|
||||
render(
|
||||
<DataLinksContextMenu
|
||||
links={() => [
|
||||
{
|
||||
href: '/link1',
|
||||
title: 'Link1',
|
||||
target: '_blank',
|
||||
origin: {},
|
||||
},
|
||||
]}
|
||||
config={{
|
||||
links: [
|
||||
{
|
||||
title: 'Link1',
|
||||
url: '/link1',
|
||||
},
|
||||
],
|
||||
}}
|
||||
>
|
||||
{() => {
|
||||
return <div aria-label="fake aria label" />;
|
||||
}}
|
||||
</DataLinksContextMenu>
|
||||
);
|
||||
|
||||
expect(screen.getByLabelText(fakeAriaLabel)).toBeInTheDocument();
|
||||
expect(screen.getByLabelText(selectors.components.DataLinksContextMenu.singleLink)).toBeInTheDocument();
|
||||
});
|
||||
});
|
@ -1,12 +1,14 @@
|
||||
import React from 'react';
|
||||
import { WithContextMenu } from '../ContextMenu/WithContextMenu';
|
||||
import { LinkModel } from '@grafana/data';
|
||||
import { linkModelToContextMenuItems } from '../../utils/dataLinks';
|
||||
import { FieldConfig, LinkModel } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { css } from 'emotion';
|
||||
import { WithContextMenu } from '../ContextMenu/WithContextMenu';
|
||||
import { linkModelToContextMenuItems } from '../../utils/dataLinks';
|
||||
|
||||
interface DataLinksContextMenuProps {
|
||||
children: (props: DataLinksContextMenuApi) => JSX.Element;
|
||||
links: () => LinkModel[];
|
||||
config: FieldConfig;
|
||||
}
|
||||
|
||||
export interface DataLinksContextMenuApi {
|
||||
@ -14,7 +16,8 @@ export interface DataLinksContextMenuApi {
|
||||
targetClassName?: string;
|
||||
}
|
||||
|
||||
export const DataLinksContextMenu: React.FC<DataLinksContextMenuProps> = ({ children, links }) => {
|
||||
export const DataLinksContextMenu: React.FC<DataLinksContextMenuProps> = ({ children, links, config }) => {
|
||||
const linksCounter = config.links!.length;
|
||||
const getDataLinksContextMenuItems = () => {
|
||||
return [{ items: linkModelToContextMenuItems(links), label: 'Data links' }];
|
||||
};
|
||||
@ -24,11 +27,27 @@ export const DataLinksContextMenu: React.FC<DataLinksContextMenuProps> = ({ chil
|
||||
cursor: context-menu;
|
||||
`;
|
||||
|
||||
return (
|
||||
<WithContextMenu getContextMenuItems={getDataLinksContextMenuItems}>
|
||||
{({ openMenu }) => {
|
||||
return children({ openMenu, targetClassName });
|
||||
}}
|
||||
</WithContextMenu>
|
||||
);
|
||||
if (linksCounter > 1) {
|
||||
return (
|
||||
<WithContextMenu getContextMenuItems={getDataLinksContextMenuItems}>
|
||||
{({ openMenu }) => {
|
||||
return children({ openMenu, targetClassName });
|
||||
}}
|
||||
</WithContextMenu>
|
||||
);
|
||||
} else {
|
||||
const linkModel = links()[0];
|
||||
return (
|
||||
<a
|
||||
href={linkModel.href}
|
||||
onClick={linkModel.onClick}
|
||||
target={linkModel.target}
|
||||
title={linkModel.title}
|
||||
style={{ display: 'flex' }}
|
||||
aria-label={selectors.components.DataLinksContextMenu.singleLink}
|
||||
>
|
||||
{children({})}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -57,14 +57,13 @@ export class BarGaugePanel extends PureComponent<PanelProps<BarGaugeOptions>> {
|
||||
|
||||
if (hasLinks && getLinks) {
|
||||
return (
|
||||
<DataLinksContextMenu links={getLinks}>
|
||||
<DataLinksContextMenu links={getLinks} config={value.field}>
|
||||
{(api) => {
|
||||
return this.renderComponent(valueProps, api);
|
||||
}}
|
||||
</DataLinksContextMenu>
|
||||
);
|
||||
}
|
||||
|
||||
return this.renderComponent(valueProps, {});
|
||||
};
|
||||
|
||||
|
@ -39,7 +39,7 @@ export class GaugePanel extends PureComponent<PanelProps<GaugeOptions>> {
|
||||
|
||||
if (hasLinks && getLinks) {
|
||||
return (
|
||||
<DataLinksContextMenu links={getLinks}>
|
||||
<DataLinksContextMenu links={getLinks} config={value.field}>
|
||||
{(api) => {
|
||||
return this.renderComponent(valueProps, api);
|
||||
}}
|
||||
|
@ -69,7 +69,7 @@ export class StatPanel extends PureComponent<PanelProps<StatPanelOptions>> {
|
||||
|
||||
if (hasLinks && getLinks) {
|
||||
return (
|
||||
<DataLinksContextMenu links={getLinks}>
|
||||
<DataLinksContextMenu links={getLinks} config={value.field}>
|
||||
{(api) => {
|
||||
return this.renderComponent(valueProps, api);
|
||||
}}
|
||||
|
Loading…
Reference in New Issue
Block a user