landingWidgetSelector.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import {useCallback, useMemo} from 'react';
  2. import styled from '@emotion/styled';
  3. import omit from 'lodash/omit';
  4. import type {SelectOption} from 'sentry/components/compactSelect';
  5. import {CompactSelect} from 'sentry/components/compactSelect';
  6. import {t} from 'sentry/locale';
  7. import {MutableSearch} from 'sentry/utils/tokenizeSearch';
  8. import useRouter from 'sentry/utils/useRouter';
  9. import {useSyncedLocalStorageState} from 'sentry/utils/useSyncedLocalStorageState';
  10. import {FunctionTrendsWidget} from './functionTrendsWidget';
  11. import {SlowestFunctionsWidget} from './slowestFunctionsWidget';
  12. export type WidgetOption =
  13. | 'slowest functions'
  14. | 'regressed functions'
  15. | 'improved functions';
  16. interface LandingWidgetSelectorProps {
  17. cursorName: string;
  18. defaultWidget: WidgetOption;
  19. query: string;
  20. storageKey: string;
  21. widgetHeight?: string;
  22. }
  23. export function LandingWidgetSelector({
  24. cursorName,
  25. defaultWidget,
  26. storageKey,
  27. widgetHeight,
  28. }: LandingWidgetSelectorProps) {
  29. const router = useRouter();
  30. const [selectedWidget, setSelectedWidget] = useSyncedLocalStorageState<WidgetOption>(
  31. storageKey,
  32. defaultWidget
  33. );
  34. const onWidgetChange = useCallback(
  35. opt => {
  36. const newQuery = omit(router.location.query, [cursorName]);
  37. router.push({
  38. pathname: router.location.pathname,
  39. query: newQuery,
  40. });
  41. setSelectedWidget(opt.value);
  42. },
  43. [cursorName, router, setSelectedWidget]
  44. );
  45. const functionQuery = useMemo(() => {
  46. const conditions = new MutableSearch('');
  47. conditions.setFilterValues('is_application', ['1']);
  48. return conditions.formatString();
  49. }, []);
  50. const header = (
  51. <StyledCompactSelect
  52. value={selectedWidget}
  53. options={WIDGET_OPTIONS}
  54. onChange={onWidgetChange}
  55. triggerProps={{borderless: true, size: 'zero'}}
  56. offset={4}
  57. />
  58. );
  59. switch (selectedWidget) {
  60. case 'slowest functions':
  61. return (
  62. <SlowestFunctionsWidget
  63. cursorName={cursorName}
  64. header={header}
  65. userQuery={functionQuery}
  66. widgetHeight={widgetHeight}
  67. />
  68. );
  69. case 'regressed functions':
  70. return (
  71. <FunctionTrendsWidget
  72. cursorName={cursorName}
  73. header={header}
  74. trendFunction="p95()"
  75. trendType="regression"
  76. userQuery={functionQuery}
  77. widgetHeight={widgetHeight}
  78. />
  79. );
  80. case 'improved functions':
  81. return (
  82. <FunctionTrendsWidget
  83. cursorName={cursorName}
  84. header={header}
  85. trendFunction="p95()"
  86. trendType="improvement"
  87. userQuery={functionQuery}
  88. widgetHeight={widgetHeight}
  89. />
  90. );
  91. default:
  92. throw new Error('unknown widget type');
  93. }
  94. }
  95. const WIDGET_OPTIONS: SelectOption<WidgetOption>[] = [
  96. {
  97. label: t('Slowest Functions'),
  98. value: 'slowest functions' as const,
  99. },
  100. {
  101. label: t('Most Regressed Functions'),
  102. value: 'regressed functions' as const,
  103. },
  104. {
  105. label: t('Most Improved Functions'),
  106. value: 'improved functions' as const,
  107. },
  108. ];
  109. const StyledCompactSelect = styled(CompactSelect)`
  110. > button {
  111. border: None;
  112. padding: 0;
  113. }
  114. `;