index.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import type {Dispatch, SetStateAction} from 'react';
  2. import {Fragment, useCallback, useMemo} from 'react';
  3. import styled from '@emotion/styled';
  4. import {openModal} from 'sentry/actionCreators/modal';
  5. import {Button} from 'sentry/components/button';
  6. import {TabList, Tabs} from 'sentry/components/tabs';
  7. import {IconTable} from 'sentry/icons/iconTable';
  8. import {t} from 'sentry/locale';
  9. import {space} from 'sentry/styles/space';
  10. import {decodeScalar} from 'sentry/utils/queryString';
  11. import {useLocation} from 'sentry/utils/useLocation';
  12. import {useNavigate} from 'sentry/utils/useNavigate';
  13. import {useResultMode} from 'sentry/views/explore/hooks/useResultsMode';
  14. import {useSampleFields} from 'sentry/views/explore/hooks/useSampleFields';
  15. import {useSpanTags} from '../contexts/spanTagsContext';
  16. import {TracesTable} from './tracesTable/index';
  17. import {AggregatesTable} from './aggregatesTable';
  18. import {ColumnEditorModal} from './columnEditorModal';
  19. import {SpansTable} from './spansTable';
  20. enum Tab {
  21. SPAN = 'span',
  22. TRACE = 'trace',
  23. }
  24. function useTab(): [Tab, (tab: Tab) => void] {
  25. const location = useLocation();
  26. const navigate = useNavigate();
  27. const tab = useMemo(() => {
  28. const rawTab = decodeScalar(location.query.table);
  29. if (rawTab === 'trace') {
  30. return Tab.TRACE;
  31. }
  32. return Tab.SPAN;
  33. }, [location.query.table]);
  34. const setTab = useCallback(
  35. (newTab: Tab) => {
  36. navigate({
  37. ...location,
  38. query: {
  39. ...location.query,
  40. table: newTab,
  41. cursor: undefined,
  42. },
  43. });
  44. },
  45. [location, navigate]
  46. );
  47. return [tab, setTab];
  48. }
  49. interface ExploreTablesProps {
  50. setError: Dispatch<SetStateAction<string>>;
  51. }
  52. export function ExploreTables({setError}: ExploreTablesProps) {
  53. const [resultMode] = useResultMode();
  54. return (
  55. <Fragment>
  56. {resultMode === 'aggregate' && <ExploreAggregatesTable setError={setError} />}
  57. {resultMode === 'samples' && <ExploreSamplesTable setError={setError} />}
  58. </Fragment>
  59. );
  60. }
  61. function ExploreAggregatesTable({setError}: ExploreTablesProps) {
  62. return <AggregatesTable setError={setError} />;
  63. }
  64. function ExploreSamplesTable({setError}: ExploreTablesProps) {
  65. const [tab, setTab] = useTab();
  66. const [fields, setFields] = useSampleFields();
  67. const numberTags = useSpanTags('number');
  68. const stringTags = useSpanTags('string');
  69. const openColumnEditor = useCallback(() => {
  70. openModal(
  71. modalProps => (
  72. <ColumnEditorModal
  73. {...modalProps}
  74. columns={fields}
  75. onColumnsChange={setFields}
  76. stringTags={stringTags}
  77. numberTags={numberTags}
  78. />
  79. ),
  80. {closeEvents: 'escape-key'}
  81. );
  82. }, [fields, setFields, stringTags, numberTags]);
  83. return (
  84. <Fragment>
  85. <SamplesTableHeader>
  86. <Tabs value={tab} onChange={setTab}>
  87. <TabList hideBorder>
  88. <TabList.Item key={Tab.SPAN}>{t('Span Samples')}</TabList.Item>
  89. <TabList.Item key={Tab.TRACE}>{t('Trace Samples')}</TabList.Item>
  90. </TabList>
  91. </Tabs>
  92. <Button
  93. disabled={tab !== Tab.SPAN}
  94. onClick={openColumnEditor}
  95. icon={<IconTable />}
  96. >
  97. {t('Edit Table')}
  98. </Button>
  99. </SamplesTableHeader>
  100. {tab === Tab.SPAN && <SpansTable setError={setError} />}
  101. {tab === Tab.TRACE && <TracesTable setError={setError} />}
  102. </Fragment>
  103. );
  104. }
  105. const SamplesTableHeader = styled('div')`
  106. display: flex;
  107. flex-direction: row;
  108. justify-content: space-between;
  109. margin-bottom: ${space(2)};
  110. `;