FunctionEditor.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import React from 'react';
  2. import { PopoverController, Popover } from '@grafana/ui';
  3. // @ts-ignore
  4. import rst2html from 'rst2html';
  5. import { FunctionDescriptor, FunctionEditorControlsProps, FunctionEditorControls } from './FunctionEditorControls';
  6. interface FunctionEditorProps extends FunctionEditorControlsProps {
  7. func: FunctionDescriptor;
  8. }
  9. interface FunctionEditorState {
  10. showingDescription: boolean;
  11. }
  12. class FunctionEditor extends React.PureComponent<FunctionEditorProps, FunctionEditorState> {
  13. private triggerRef = React.createRef<HTMLSpanElement>();
  14. constructor(props: FunctionEditorProps) {
  15. super(props);
  16. this.state = {
  17. showingDescription: false,
  18. };
  19. }
  20. renderContent = ({ updatePopperPosition }: any) => {
  21. const {
  22. onMoveLeft,
  23. onMoveRight,
  24. func: {
  25. def: { name, description },
  26. },
  27. } = this.props;
  28. const { showingDescription } = this.state;
  29. if (showingDescription) {
  30. return (
  31. <div style={{ overflow: 'auto', maxHeight: '30rem', textAlign: 'left', fontWeight: 'normal' }}>
  32. <h4 style={{ color: 'white' }}> {name} </h4>
  33. <div
  34. dangerouslySetInnerHTML={{
  35. __html: rst2html(description),
  36. }}
  37. />
  38. </div>
  39. );
  40. }
  41. return (
  42. <FunctionEditorControls
  43. {...this.props}
  44. onMoveLeft={() => {
  45. onMoveLeft(this.props.func);
  46. updatePopperPosition();
  47. }}
  48. onMoveRight={() => {
  49. onMoveRight(this.props.func);
  50. updatePopperPosition();
  51. }}
  52. onDescriptionShow={() => {
  53. this.setState({ showingDescription: true }, () => {
  54. updatePopperPosition();
  55. });
  56. }}
  57. />
  58. );
  59. };
  60. render() {
  61. return (
  62. <PopoverController content={this.renderContent} placement="top" hideAfter={300}>
  63. {(showPopper, hidePopper, popperProps) => {
  64. return (
  65. <>
  66. {this.triggerRef && (
  67. <Popover
  68. {...popperProps}
  69. referenceElement={this.triggerRef.current}
  70. wrapperClassName="popper"
  71. className="popper__background"
  72. onMouseLeave={() => {
  73. this.setState({ showingDescription: false });
  74. hidePopper();
  75. }}
  76. onMouseEnter={showPopper}
  77. renderArrow={({ arrowProps, placement }) => (
  78. <div className="popper__arrow" data-placement={placement} {...arrowProps} />
  79. )}
  80. />
  81. )}
  82. <span
  83. ref={this.triggerRef}
  84. onClick={popperProps.show ? hidePopper : showPopper}
  85. onMouseLeave={() => {
  86. hidePopper();
  87. this.setState({ showingDescription: false });
  88. }}
  89. style={{ cursor: 'pointer' }}
  90. >
  91. {this.props.func.def.name}
  92. </span>
  93. </>
  94. );
  95. }}
  96. </PopoverController>
  97. );
  98. }
  99. }
  100. export { FunctionEditor };