tracePreferencesDropdown.tsx 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import {useCallback, useMemo} from 'react';
  2. import {CompactSelect, type SelectOption} from 'sentry/components/compactSelect';
  3. import type {DropdownButtonProps} from 'sentry/components/dropdownButton';
  4. import {IconSettings} from 'sentry/icons';
  5. import {t} from 'sentry/locale';
  6. const CompactSelectTriggerProps: DropdownButtonProps = {
  7. icon: <IconSettings />,
  8. showChevron: false,
  9. size: 'xs' as const,
  10. 'aria-label': t('Trace Preferences'),
  11. };
  12. interface TracePreferencesDropdownProps {
  13. autogroup: boolean;
  14. missingInstrumentation: boolean;
  15. onAutogroupChange: () => void;
  16. onMissingInstrumentationChange: () => void;
  17. }
  18. const TRACE_PREFERENCES_DROPDOWN_OPTIONS: SelectOption<string>[] = [
  19. {
  20. label: t('Autogrouping'),
  21. value: 'autogroup',
  22. details: t(
  23. 'Collapses 5 or more sibling spans with the same description or any spans with 2 or more descendants with the same operation.'
  24. ),
  25. },
  26. {
  27. label: t('Missing Instrumentation'),
  28. value: 'missing-instrumentation',
  29. details: t(
  30. 'Shows when there is more than 100ms of unaccounted elapsed time between two spans.'
  31. ),
  32. },
  33. ];
  34. export function TracePreferencesDropdown(props: TracePreferencesDropdownProps) {
  35. const values = useMemo(() => {
  36. const value: string[] = [];
  37. if (props.autogroup) {
  38. value.push('autogroup');
  39. }
  40. if (props.missingInstrumentation) {
  41. value.push('missing-instrumentation');
  42. }
  43. return value;
  44. }, [props.autogroup, props.missingInstrumentation]);
  45. const onAutogroupChange = props.onAutogroupChange;
  46. const onMissingInstrumentationChange = props.onMissingInstrumentationChange;
  47. const onChange = useCallback(
  48. (newValues: SelectOption<string>[]) => {
  49. const newValuesArray = newValues.map(v => v.value);
  50. if (values.length < newValuesArray.length) {
  51. const newOption = newValuesArray.find(v => !values.includes(v));
  52. if (newOption === 'autogroup') {
  53. onAutogroupChange();
  54. }
  55. if (newOption === 'missing-instrumentation') {
  56. onMissingInstrumentationChange();
  57. }
  58. }
  59. if (values.length > newValuesArray.length) {
  60. const removedOption = values.find(v => !newValuesArray.includes(v));
  61. if (removedOption === 'autogroup') {
  62. onAutogroupChange();
  63. }
  64. if (removedOption === 'missing-instrumentation') {
  65. onMissingInstrumentationChange();
  66. }
  67. }
  68. },
  69. [values, onAutogroupChange, onMissingInstrumentationChange]
  70. );
  71. return (
  72. <CompactSelect
  73. multiple
  74. value={values}
  75. // Force the trigger to be so that we only render the icon
  76. triggerLabel=""
  77. triggerProps={CompactSelectTriggerProps}
  78. options={TRACE_PREFERENCES_DROPDOWN_OPTIONS}
  79. onChange={onChange}
  80. />
  81. );
  82. }