tracePreferencesDropdown.tsx 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. export function TracePreferencesDropdown(props: TracePreferencesDropdownProps) {
  19. const options: SelectOption<string>[] = useMemo(
  20. () => [
  21. {
  22. label: t('Autogrouping'),
  23. value: 'autogroup',
  24. details: t(
  25. 'Collapses 5 or more sibling spans with the same description or any spans with 2 or more descendants with the same operation.'
  26. ),
  27. },
  28. {
  29. label: t('Missing Instrumentation'),
  30. value: 'missing-instrumentation',
  31. details: t(
  32. 'Shows when there is more than 100ms of unaccounted elapsed time between two spans.'
  33. ),
  34. },
  35. ],
  36. []
  37. );
  38. const values = useMemo(() => {
  39. const value: string[] = [];
  40. if (props.autogroup) {
  41. value.push('autogroup');
  42. }
  43. if (props.missingInstrumentation) {
  44. value.push('missing-instrumentation');
  45. }
  46. return value;
  47. }, [props.autogroup, props.missingInstrumentation]);
  48. const onAutogroupChange = props.onAutogroupChange;
  49. const onMissingInstrumentationChange = props.onMissingInstrumentationChange;
  50. const onChange = useCallback(
  51. (newValues: SelectOption<string>[]) => {
  52. const newValuesArray = newValues.map(v => v.value);
  53. if (values.length < newValuesArray.length) {
  54. const newOption = newValuesArray.find(v => !values.includes(v));
  55. if (newOption === 'autogroup') {
  56. onAutogroupChange();
  57. }
  58. if (newOption === 'missing-instrumentation') {
  59. onMissingInstrumentationChange();
  60. }
  61. }
  62. if (values.length > newValuesArray.length) {
  63. const removedOption = values.find(v => !newValuesArray.includes(v));
  64. if (removedOption === 'autogroup') {
  65. onAutogroupChange();
  66. }
  67. if (removedOption === 'missing-instrumentation') {
  68. onMissingInstrumentationChange();
  69. }
  70. }
  71. },
  72. [values, onAutogroupChange, onMissingInstrumentationChange]
  73. );
  74. return (
  75. <CompactSelect
  76. multiple
  77. value={values}
  78. // Force the trigger to be so that we only render the icon
  79. triggerLabel=""
  80. triggerProps={CompactSelectTriggerProps}
  81. options={options}
  82. onChange={onChange}
  83. />
  84. );
  85. }