widgetDetails.tsx 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import {useState} from 'react';
  2. import styled from '@emotion/styled';
  3. import EmptyMessage from 'sentry/components/emptyMessage';
  4. import {TabList, Tabs} from 'sentry/components/tabs';
  5. import {Tooltip} from 'sentry/components/tooltip';
  6. import {IconSearch} from 'sentry/icons';
  7. import {t} from 'sentry/locale';
  8. import {space} from 'sentry/styles/space';
  9. import {isCustomMetric, MetricWidgetQueryParams} from 'sentry/utils/metrics';
  10. import {CodeLocations} from 'sentry/views/ddm/codeLocations';
  11. import {useDDMContext} from 'sentry/views/ddm/context';
  12. import {TraceTable} from 'sentry/views/ddm/samplesTable';
  13. enum Tab {
  14. SAMPLES = 'samples',
  15. CODE_LOCATIONS = 'codeLocations',
  16. }
  17. export function WidgetDetails() {
  18. const {selectedWidgetIndex, widgets, focusArea} = useDDMContext();
  19. const [selectedTab, setSelectedTab] = useState(Tab.CODE_LOCATIONS);
  20. // the tray is minimized when the main content is maximized
  21. const selectedWidget = widgets[selectedWidgetIndex] as
  22. | MetricWidgetQueryParams
  23. | undefined;
  24. const isCodeLocationsDisabled =
  25. selectedWidget?.mri && !isCustomMetric({mri: selectedWidget.mri});
  26. if (isCodeLocationsDisabled && selectedTab === Tab.CODE_LOCATIONS) {
  27. setSelectedTab(Tab.SAMPLES);
  28. }
  29. return (
  30. <TrayWrapper>
  31. <Tabs value={selectedTab} onChange={setSelectedTab}>
  32. <TabList>
  33. <TabList.Item
  34. textValue={t('Code Location')}
  35. key={Tab.CODE_LOCATIONS}
  36. disabled={isCodeLocationsDisabled}
  37. >
  38. <Tooltip
  39. title={t(
  40. 'This metric is automatically collected by Sentry. It is not bound to a specific line of your code.'
  41. )}
  42. disabled={!isCodeLocationsDisabled}
  43. >
  44. <span style={{pointerEvents: 'all'}}>{t('Code Location')}</span>
  45. </Tooltip>
  46. </TabList.Item>
  47. <TabList.Item key={Tab.SAMPLES}>{t('Samples')}</TabList.Item>
  48. </TabList>
  49. </Tabs>
  50. <ContentWrapper>
  51. {!selectedWidget?.mri ? (
  52. <CenterContent>
  53. <EmptyMessage
  54. style={{margin: 'auto'}}
  55. icon={<IconSearch size="xxl" />}
  56. title={t('Nothing to show!')}
  57. description={t('Choose a metric to display data.')}
  58. />
  59. </CenterContent>
  60. ) : selectedTab === Tab.SAMPLES ? (
  61. <TraceTable mri={selectedWidget.mri} {...focusArea?.range} />
  62. ) : (
  63. <CodeLocations mri={selectedWidget.mri} {...focusArea?.range} />
  64. )}
  65. </ContentWrapper>
  66. </TrayWrapper>
  67. );
  68. }
  69. const TrayWrapper = styled('div')`
  70. padding-top: ${space(4)};
  71. display: grid;
  72. grid-template-rows: auto auto 1fr;
  73. `;
  74. const ContentWrapper = styled('div')`
  75. position: relative;
  76. padding: ${space(2)} 0;
  77. overflow: auto;
  78. `;
  79. const CenterContent = styled('div')`
  80. display: flex;
  81. justify-content: center;
  82. align-items: center;
  83. height: 100%;
  84. `;