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;