mirror of https://github.com/grafana/grafana
Canvas: Add tooltip for data links (#61648)
parent
c1251311d0
commit
cef15873d6
@ -0,0 +1,80 @@ |
|||||||
|
import { css } from '@emotion/css'; |
||||||
|
import { useDialog } from '@react-aria/dialog'; |
||||||
|
import { useOverlay } from '@react-aria/overlays'; |
||||||
|
import React, { createRef } from 'react'; |
||||||
|
|
||||||
|
import { GrafanaTheme2, LinkModel } from '@grafana/data/src'; |
||||||
|
import { LinkButton, Portal, useStyles2, VerticalGroup, VizTooltipContainer } from '@grafana/ui'; |
||||||
|
import { CloseButton } from 'app/core/components/CloseButton/CloseButton'; |
||||||
|
import { Scene } from 'app/features/canvas/runtime/scene'; |
||||||
|
|
||||||
|
interface Props { |
||||||
|
scene: Scene; |
||||||
|
} |
||||||
|
|
||||||
|
export const CanvasTooltip = ({ scene }: Props) => { |
||||||
|
const style = useStyles2(getStyles); |
||||||
|
|
||||||
|
const onClose = () => { |
||||||
|
if (scene?.tooltipCallback && scene.tooltip) { |
||||||
|
scene.tooltipCallback(undefined); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
const ref = createRef<HTMLElement>(); |
||||||
|
const { overlayProps } = useOverlay({ onClose: onClose, isDismissable: true }, ref); |
||||||
|
const { dialogProps } = useDialog({}, ref); |
||||||
|
|
||||||
|
const element = scene.tooltip?.element; |
||||||
|
if (!element) { |
||||||
|
return <></>; |
||||||
|
} |
||||||
|
|
||||||
|
const renderDataLinks = () => |
||||||
|
element.data?.links && |
||||||
|
element.data?.links.length > 0 && ( |
||||||
|
<div> |
||||||
|
<VerticalGroup> |
||||||
|
{element.data?.links?.map((link: LinkModel, i: number) => ( |
||||||
|
<LinkButton |
||||||
|
key={i} |
||||||
|
icon={'external-link-alt'} |
||||||
|
target={link.target} |
||||||
|
href={link.href} |
||||||
|
onClick={link.onClick} |
||||||
|
fill="text" |
||||||
|
style={{ width: '100%' }} |
||||||
|
> |
||||||
|
{link.title} |
||||||
|
</LinkButton> |
||||||
|
))} |
||||||
|
</VerticalGroup> |
||||||
|
</div> |
||||||
|
); |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
{scene.tooltip?.element && scene.tooltip.anchorPoint && ( |
||||||
|
<Portal> |
||||||
|
<VizTooltipContainer |
||||||
|
position={{ x: scene.tooltip.anchorPoint.x, y: scene.tooltip.anchorPoint.y }} |
||||||
|
offset={{ x: 5, y: 0 }} |
||||||
|
allowPointerEvents={scene.tooltip.isOpen} |
||||||
|
> |
||||||
|
<section ref={ref} {...overlayProps} {...dialogProps}> |
||||||
|
{scene.tooltip.isOpen && <CloseButton style={{ zIndex: 1 }} onClick={onClose} />} |
||||||
|
<div className={style.wrapper}>{renderDataLinks()}</div> |
||||||
|
</section> |
||||||
|
</VizTooltipContainer> |
||||||
|
</Portal> |
||||||
|
)} |
||||||
|
</> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
const getStyles = (theme: GrafanaTheme2) => ({ |
||||||
|
wrapper: css` |
||||||
|
margin-top: 20px; |
||||||
|
background: ${theme.colors.background.primary}; |
||||||
|
`,
|
||||||
|
}); |
Loading…
Reference in new issue