github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/webapp/javascript/pages/continuous/contextMenu/AddAnnotation.menuitem.tsx (about) 1 /* eslint-disable react/jsx-props-no-spreading */ 2 import React, { useState } from 'react'; 3 import { MenuItem } from '@webapp/ui/Menu'; 4 import { 5 Popover, 6 PopoverBody, 7 PopoverFooter, 8 PopoverHeader, 9 } from '@webapp/ui/Popover'; 10 import Button from '@webapp/ui/Button'; 11 import { Portal, PortalProps } from '@webapp/ui/Portal'; 12 import { NewAnnotation } from '@webapp/services/annotations'; 13 import TextField from '@webapp/ui/Form/TextField'; 14 import { useAnnotationForm } from './useAnnotationForm'; 15 import styles from './AddAnnotation.menuitem.module.css'; 16 17 export interface AddAnnotationProps { 18 /** where to put the popover in the DOM */ 19 container: PortalProps['container']; 20 21 /** where to position the popover */ 22 popoverAnchorPoint: { 23 x: number; 24 y: number; 25 }; 26 27 onCreateAnnotation: (content: NewAnnotation['content']) => void; 28 timestamp: number; 29 timezone: 'browser' | 'utc'; 30 } 31 32 function AddAnnotation(props: AddAnnotationProps) { 33 const { 34 container, 35 popoverAnchorPoint, 36 onCreateAnnotation, 37 timestamp, 38 timezone, 39 } = props; 40 const [isPopoverOpen, setPopoverOpen] = useState(false); 41 const { register, handleSubmit, errors, setFocus } = useAnnotationForm({ 42 timezone, 43 value: { timestamp }, 44 }); 45 46 // Focus on the only input 47 React.useEffect(() => { 48 if (isPopoverOpen) { 49 setFocus('content'); 50 } 51 }, [setFocus, isPopoverOpen]); 52 53 const popoverContent = isPopoverOpen ? ( 54 <> 55 <PopoverHeader>Add annotation</PopoverHeader> 56 <PopoverBody> 57 <form 58 id="annotation-form" 59 name="annotation-form" 60 className={styles.form} 61 onSubmit={handleSubmit((d) => { 62 onCreateAnnotation(d.content as string); 63 })} 64 > 65 <TextField 66 {...register('content')} 67 label="Description" 68 variant="light" 69 errorMessage={errors.content?.message} 70 data-testid="annotation_content_input" 71 /> 72 <TextField 73 {...register('timestamp')} 74 label="Time" 75 type="text" 76 readOnly 77 data-testid="annotation_timestamp_input" 78 /> 79 </form> 80 </PopoverBody> 81 <PopoverFooter> 82 <Button type="submit" kind="secondary" form="annotation-form"> 83 Save 84 </Button> 85 </PopoverFooter> 86 </> 87 ) : null; 88 89 return ( 90 <> 91 <MenuItem key="focus" onClick={() => setPopoverOpen(true)}> 92 Add annotation 93 </MenuItem> 94 <Portal container={container}> 95 <Popover 96 anchorPoint={{ x: popoverAnchorPoint.x, y: popoverAnchorPoint.y }} 97 isModalOpen 98 setModalOpenStatus={setPopoverOpen} 99 > 100 {popoverContent} 101 </Popover> 102 </Portal> 103 </> 104 ); 105 } 106 107 export default AddAnnotation;