github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/packages/pyroscope-flamegraph/src/SharedQueryInput.tsx (about)

     1  /* eslint-disable no-unused-expressions */
     2  import React, { useEffect, useMemo, ChangeEvent, useRef } from 'react';
     3  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
     4  import { faLink } from '@fortawesome/free-solid-svg-icons/faLink';
     5  import Input from '@pyroscope/webapp/javascript/ui/Input';
     6  import { Tooltip } from '@pyroscope/webapp/javascript/ui/Tooltip';
     7  import styles from './SharedQueryInput.module.scss';
     8  import type { ProfileHeaderProps } from './Toolbar';
     9  
    10  interface SharedQueryProps {
    11    onHighlightChange: ProfileHeaderProps['handleSearchChange'];
    12    highlightQuery: ProfileHeaderProps['highlightQuery'];
    13    sharedQuery: ProfileHeaderProps['sharedQuery'];
    14    width: number;
    15  }
    16  
    17  const usePreviousSyncEnabled = (syncEnabled?: string | boolean) => {
    18    const ref = useRef();
    19  
    20    useEffect(() => {
    21      (ref.current as string | boolean | undefined) = syncEnabled;
    22    });
    23  
    24    return ref.current;
    25  };
    26  
    27  const SharedQueryInput = ({
    28    onHighlightChange,
    29    highlightQuery,
    30    sharedQuery,
    31    width,
    32  }: SharedQueryProps) => {
    33    const prevSyncEnabled = usePreviousSyncEnabled(sharedQuery?.syncEnabled);
    34  
    35    const onQueryChange = (e: ChangeEvent<HTMLInputElement>) => {
    36      onHighlightChange(e.target.value);
    37  
    38      if (sharedQuery && sharedQuery.syncEnabled) {
    39        sharedQuery.onQueryChange(e.target.value);
    40      }
    41    };
    42  
    43    useEffect(() => {
    44      if (typeof sharedQuery?.searchQuery === 'string') {
    45        if (sharedQuery.syncEnabled) {
    46          onHighlightChange(sharedQuery.searchQuery);
    47        }
    48  
    49        if (
    50          !sharedQuery.syncEnabled &&
    51          prevSyncEnabled &&
    52          prevSyncEnabled !== sharedQuery?.id
    53        ) {
    54          onHighlightChange('');
    55        }
    56      }
    57    }, [sharedQuery?.searchQuery, sharedQuery?.syncEnabled]);
    58  
    59    const onToggleSync = () => {
    60      const newValue = sharedQuery?.syncEnabled ? false : sharedQuery?.id;
    61      sharedQuery?.toggleSync(newValue as string | false);
    62  
    63      if (newValue) {
    64        sharedQuery?.onQueryChange(highlightQuery);
    65      } else {
    66        onHighlightChange(highlightQuery);
    67        sharedQuery?.onQueryChange('');
    68      }
    69    };
    70  
    71    const inputValue = useMemo(
    72      () =>
    73        sharedQuery && sharedQuery.syncEnabled
    74          ? sharedQuery.searchQuery || ''
    75          : highlightQuery,
    76      [sharedQuery, highlightQuery]
    77    );
    78  
    79    const inputClassName = useMemo(
    80      () =>
    81        `${sharedQuery ? styles.searchWithSync : styles.search} ${
    82          sharedQuery?.syncEnabled ? styles['search-synced'] : ''
    83        }`,
    84      [sharedQuery]
    85    );
    86  
    87    return (
    88      <div className={styles.wrapper} style={{ width }}>
    89        <Input
    90          testId="flamegraph-search"
    91          className={inputClassName}
    92          type="search"
    93          name="flamegraph-search"
    94          placeholder="Search…"
    95          minLength={2}
    96          debounceTimeout={100}
    97          onChange={onQueryChange}
    98          value={inputValue}
    99        />
   100        {sharedQuery ? (
   101          <Tooltip
   102            placement="top"
   103            title={
   104              sharedQuery.syncEnabled ? 'Unsync search bars' : 'Sync search bars'
   105            }
   106          >
   107            <button
   108              className={
   109                sharedQuery.syncEnabled ? styles.syncSelected : styles.sync
   110              }
   111              onClick={onToggleSync}
   112            >
   113              <FontAwesomeIcon
   114                className={`${
   115                  sharedQuery.syncEnabled ? styles.checked : styles.icon
   116                }`}
   117                icon={faLink}
   118              />
   119            </button>
   120          </Tooltip>
   121        ) : null}
   122      </div>
   123    );
   124  };
   125  
   126  export default SharedQueryInput;