github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/webapp/javascript/components/TimelineChart/AnnotationMark/index.tsx (about) 1 /* eslint-disable default-case, consistent-return */ 2 import Color from 'color'; 3 import React, { useState } from 'react'; 4 import classNames from 'classnames/bind'; 5 import AnnotationInfo from '@webapp/pages/continuous/contextMenu/AnnotationInfo'; 6 import useTimeZone from '@webapp/hooks/timeZone.hook'; 7 8 import styles from './styles.module.scss'; 9 10 const cx = classNames.bind(styles); 11 12 interface IAnnotationMarkProps { 13 type: 'message'; 14 color: Color; 15 value: { 16 content: string; 17 timestamp: number; 18 }; 19 posX: number; 20 } 21 22 const getIcon = (type: IAnnotationMarkProps['type']) => { 23 switch (type) { 24 case 'message': 25 return styles.message; 26 } 27 }; 28 29 const AnnotationMark = ({ type, color, value, posX }: IAnnotationMarkProps) => { 30 const { offset } = useTimeZone(); 31 const [visible, setVisible] = useState(false); 32 const [target, setTarget] = useState<Element>(); 33 const [hovered, setHovered] = useState(false); 34 35 const onClick = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => { 36 e.stopPropagation(); 37 setTarget(e.target as Element); 38 setVisible(true); 39 }; 40 41 // TODO: 150 refers to the timeline height, clean this up 42 const pos = { x: posX, y: 150 }; 43 const annotationInfoPopover = target ? ( 44 <AnnotationInfo 45 popoverAnchorPoint={pos} 46 value={value} 47 timezone={offset === 0 ? 'utc' : 'browser'} 48 timestamp={value.timestamp} 49 isOpen={visible} 50 onClose={() => setVisible(false)} 51 popoverClassname={styles.form} 52 /> 53 ) : null; 54 55 const onHoverStyle = { 56 backgroundColor: hovered ? color.darken(0.2).hex() : color.hex(), 57 zIndex: hovered ? 2 : 1, 58 }; 59 60 return ( 61 <> 62 <div 63 data-testid="annotation_mark_wrapper" 64 onClick={onClick} 65 style={onHoverStyle} 66 className={cx(styles.wrapper, getIcon(type))} 67 role="none" 68 onMouseEnter={() => setHovered(true)} 69 onMouseLeave={() => setHovered(false)} 70 /> 71 {annotationInfoPopover} 72 </> 73 ); 74 }; 75 76 export default AnnotationMark;