PanelHeaderCorner.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import React, { Component } from 'react';
  2. import { renderMarkdown, LinkModelSupplier, ScopedVars } from '@grafana/data';
  3. import { Tooltip, PopoverContent } from '@grafana/ui';
  4. import { PanelModel } from 'app/features/dashboard/state/PanelModel';
  5. import templateSrv from 'app/features/templating/template_srv';
  6. import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv';
  7. enum InfoMode {
  8. Error = 'Error',
  9. Info = 'Info',
  10. Links = 'Links',
  11. }
  12. interface Props {
  13. panel: PanelModel;
  14. title?: string;
  15. description?: string;
  16. scopedVars?: ScopedVars;
  17. links?: LinkModelSupplier<PanelModel>;
  18. error?: string;
  19. }
  20. export class PanelHeaderCorner extends Component<Props> {
  21. timeSrv: TimeSrv = getTimeSrv();
  22. getInfoMode = () => {
  23. const { panel, error } = this.props;
  24. if (error) {
  25. return InfoMode.Error;
  26. }
  27. if (!!panel.description) {
  28. return InfoMode.Info;
  29. }
  30. if (panel.links && panel.links.length) {
  31. return InfoMode.Links;
  32. }
  33. return undefined;
  34. };
  35. getInfoContent = (): JSX.Element => {
  36. const { panel } = this.props;
  37. const markdown = panel.description || '';
  38. const interpolatedMarkdown = templateSrv.replace(markdown, panel.scopedVars);
  39. const markedInterpolatedMarkdown = renderMarkdown(interpolatedMarkdown);
  40. const links = this.props.links && this.props.links.getLinks(panel);
  41. return (
  42. <div className="panel-info-content markdown-html">
  43. <div dangerouslySetInnerHTML={{ __html: markedInterpolatedMarkdown }} />
  44. {links && links.length > 0 && (
  45. <ul className="panel-info-corner-links">
  46. {links.map((link, idx) => {
  47. return (
  48. <li key={idx}>
  49. <a className="panel-info-corner-links__item" href={link.href} target={link.target}>
  50. {link.title}
  51. </a>
  52. </li>
  53. );
  54. })}
  55. </ul>
  56. )}
  57. </div>
  58. );
  59. };
  60. renderCornerType(infoMode: InfoMode, content: PopoverContent) {
  61. const theme = infoMode === InfoMode.Error ? 'error' : 'info';
  62. return (
  63. <Tooltip content={content} placement="top-start" theme={theme}>
  64. <div className={`panel-info-corner panel-info-corner--${infoMode.toLowerCase()}`}>
  65. <i className="fa" />
  66. <span className="panel-info-corner-inner" />
  67. </div>
  68. </Tooltip>
  69. );
  70. }
  71. render() {
  72. const infoMode: InfoMode | undefined = this.getInfoMode();
  73. if (!infoMode) {
  74. return null;
  75. }
  76. if (infoMode === InfoMode.Error) {
  77. return this.renderCornerType(infoMode, this.props.error);
  78. }
  79. if (infoMode === InfoMode.Info || infoMode === InfoMode.Links) {
  80. return this.renderCornerType(infoMode, this.getInfoContent);
  81. }
  82. return null;
  83. }
  84. }
  85. export default PanelHeaderCorner;