flamegraphOptionsContextMenu.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import {Fragment} from 'react';
  2. import {t} from 'sentry/locale';
  3. import {
  4. FlamegraphAxisOptions,
  5. FlamegraphColorCodings,
  6. FlamegraphSorting,
  7. FlamegraphViewOptions,
  8. } from 'sentry/utils/profiling/flamegraph/flamegraphStateProvider/reducers/flamegraphPreferences';
  9. import {useFlamegraphPreferences} from 'sentry/utils/profiling/flamegraph/hooks/useFlamegraphPreferences';
  10. import {useDispatchFlamegraphState} from 'sentry/utils/profiling/flamegraph/hooks/useFlamegraphState';
  11. import {useContextMenu} from 'sentry/utils/profiling/hooks/useContextMenu';
  12. import {
  13. ProfilingContextMenu,
  14. ProfilingContextMenuGroup,
  15. ProfilingContextMenuHeading,
  16. ProfilingContextMenuItemCheckbox,
  17. ProfilingContextMenuLayer,
  18. } from './ProfilingContextMenu/profilingContextMenu';
  19. const FLAMEGRAPH_COLOR_CODINGS: FlamegraphColorCodings = [
  20. 'by symbol name',
  21. 'by system / application',
  22. 'by library',
  23. 'by recursion',
  24. 'by frequency',
  25. ];
  26. const FLAMEGRAPH_VIEW_OPTIONS: FlamegraphViewOptions = ['top down', 'bottom up'];
  27. const FLAMEGRAPH_SORTING_OPTIONS: FlamegraphSorting = ['left heavy', 'call order'];
  28. const FLAMEGRAPH_AXIS_OPTIONS: FlamegraphAxisOptions = ['standalone', 'transaction'];
  29. interface FlameGraphOptionsContextMenuProps {
  30. contextMenu: ReturnType<typeof useContextMenu>;
  31. }
  32. export function FlamegraphOptionsContextMenu(props: FlameGraphOptionsContextMenuProps) {
  33. const preferences = useFlamegraphPreferences();
  34. const dispatch = useDispatchFlamegraphState();
  35. return props.contextMenu.open ? (
  36. <Fragment>
  37. <ProfilingContextMenuLayer onClick={() => props.contextMenu.setOpen(false)} />
  38. <ProfilingContextMenu
  39. {...props.contextMenu.getMenuProps()}
  40. style={{
  41. position: 'absolute',
  42. left: props.contextMenu.position?.left ?? -9999,
  43. top: props.contextMenu.position?.top ?? -9999,
  44. maxHeight: props.contextMenu.containerCoordinates?.height ?? 'auto',
  45. }}
  46. >
  47. <ProfilingContextMenuGroup>
  48. <ProfilingContextMenuHeading>{t('Color Coding')}</ProfilingContextMenuHeading>
  49. {FLAMEGRAPH_COLOR_CODINGS.map((coding, idx) => (
  50. <ProfilingContextMenuItemCheckbox
  51. key={idx}
  52. {...props.contextMenu.getMenuItemProps()}
  53. onClick={() => dispatch({type: 'set color coding', payload: coding})}
  54. checked={preferences.colorCoding === coding}
  55. >
  56. {coding}
  57. </ProfilingContextMenuItemCheckbox>
  58. ))}
  59. </ProfilingContextMenuGroup>
  60. <ProfilingContextMenuGroup>
  61. <ProfilingContextMenuHeading>{t('View')}</ProfilingContextMenuHeading>
  62. {FLAMEGRAPH_VIEW_OPTIONS.map((view, idx) => (
  63. <ProfilingContextMenuItemCheckbox
  64. key={idx}
  65. {...props.contextMenu.getMenuItemProps()}
  66. onClick={() => dispatch({type: 'set view', payload: view})}
  67. checked={preferences.view === view}
  68. >
  69. {view}
  70. </ProfilingContextMenuItemCheckbox>
  71. ))}
  72. </ProfilingContextMenuGroup>
  73. <ProfilingContextMenuGroup>
  74. <ProfilingContextMenuHeading>{t('Sorting')}</ProfilingContextMenuHeading>
  75. {FLAMEGRAPH_SORTING_OPTIONS.map((sorting, idx) => (
  76. <ProfilingContextMenuItemCheckbox
  77. key={idx}
  78. {...props.contextMenu.getMenuItemProps()}
  79. onClick={() => dispatch({type: 'set sorting', payload: sorting})}
  80. checked={preferences.sorting === sorting}
  81. >
  82. {sorting}
  83. </ProfilingContextMenuItemCheckbox>
  84. ))}
  85. </ProfilingContextMenuGroup>
  86. <ProfilingContextMenuGroup>
  87. <ProfilingContextMenuHeading>{t('X Axis')}</ProfilingContextMenuHeading>
  88. {FLAMEGRAPH_AXIS_OPTIONS.map((axis, idx) => (
  89. <ProfilingContextMenuItemCheckbox
  90. key={idx}
  91. {...props.contextMenu.getMenuItemProps()}
  92. onClick={() => dispatch({type: 'set xAxis', payload: axis})}
  93. checked={preferences.xAxis === axis}
  94. >
  95. {axis}
  96. </ProfilingContextMenuItemCheckbox>
  97. ))}
  98. </ProfilingContextMenuGroup>
  99. </ProfilingContextMenu>
  100. </Fragment>
  101. ) : null;
  102. }