github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/webapp/javascript/pages/TracingSingleView.tsx (about)

     1  import React, { useEffect } from 'react';
     2  import 'react-dom';
     3  import { format } from 'date-fns';
     4  import { useAppDispatch, useAppSelector } from '@webapp/redux/hooks';
     5  import Box from '@webapp/ui/Box';
     6  import { FlamegraphRenderer } from '@pyroscope/flamegraph/src/FlamegraphRenderer';
     7  import { fetchSingleView } from '@webapp/redux/reducers/tracing';
     8  import useColorMode from '@webapp/hooks/colorMode.hook';
     9  import ExportData from '@webapp/components/ExportData';
    10  import useExportToFlamegraphDotCom from '@webapp/components/exportToFlamegraphDotCom.hook';
    11  import PageTitle from '@webapp/components/PageTitle';
    12  import { isExportToFlamegraphDotComEnabled } from '@webapp/util/features';
    13  import { formatTitle } from './formatTitle';
    14  
    15  import styles from './TracingSingleView.module.scss';
    16  
    17  function formatTime(t: string | undefined): string {
    18    return format(new Date(1000 * parseInt(t || '0', 10)), 'yyyy-MM-dd HH:mm:ss');
    19  }
    20  
    21  function TracingSingleView() {
    22    const dispatch = useAppDispatch();
    23    const { colorMode } = useColorMode();
    24  
    25    const { queryID, refreshToken, maxNodes, singleView } = useAppSelector(
    26      (state) => state.tracing
    27    );
    28  
    29    useEffect(() => {
    30      if (queryID && maxNodes) {
    31        const fetchData = dispatch(fetchSingleView(null));
    32        return () => fetchData.abort('cancel');
    33      }
    34      return undefined;
    35    }, [queryID, refreshToken, maxNodes]);
    36  
    37    const getRaw = () => {
    38      switch (singleView.type) {
    39        case 'loaded':
    40        case 'reloading': {
    41          return singleView.profile;
    42        }
    43  
    44        default: {
    45          return undefined;
    46        }
    47      }
    48    };
    49    const exportToFlamegraphDotComFn = useExportToFlamegraphDotCom(getRaw());
    50  
    51    const flamegraphRenderer = (() => {
    52      switch (singleView.type) {
    53        case 'loaded':
    54        case 'reloading': {
    55          return (
    56            <FlamegraphRenderer
    57              showCredit={false}
    58              profile={singleView.profile}
    59              colorMode={colorMode}
    60              ExportData={
    61                <ExportData
    62                  flamebearer={singleView.profile}
    63                  exportPNG
    64                  exportJSON
    65                  exportPprof
    66                  exportHTML
    67                  exportFlamegraphDotCom={isExportToFlamegraphDotComEnabled}
    68                  exportFlamegraphDotComFn={exportToFlamegraphDotComFn}
    69                />
    70              }
    71            />
    72          );
    73        }
    74  
    75        default: {
    76          return 'Loading';
    77        }
    78      }
    79    })();
    80  
    81    const header = singleView.mergeMetadata
    82      ? (function (mm) {
    83          const { appName, startTime, endTime, profilesLength } = mm;
    84          return (
    85            <>
    86              <div>
    87                <strong>App Name:</strong> <span>{appName}</span>
    88              </div>
    89              <div>
    90                <strong>Start Time:</strong> <span>{formatTime(startTime)}</span>
    91              </div>
    92              <div>
    93                <strong>End Time:</strong> <span>{formatTime(endTime)}</span>
    94              </div>
    95              <div>
    96                <strong>Number of Profiles merged:</strong>{' '}
    97                <span>{profilesLength}</span>
    98              </div>
    99            </>
   100          );
   101        })(singleView.mergeMetadata)
   102      : null;
   103  
   104    return (
   105      <div>
   106        <PageTitle title={formatTitle('Tracing')} />
   107        <div className="main-wrapper">
   108          <Box className={styles.header}>{header}</Box>
   109          <Box>{flamegraphRenderer}</Box>
   110        </div>
   111      </div>
   112    );
   113  }
   114  
   115  export default TracingSingleView;