queryRow.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import {Button} from 'sentry/components/button';
  4. import {LazyRender} from 'sentry/components/lazyRender';
  5. import {IconDelete} from 'sentry/icons/iconDelete';
  6. import {t} from 'sentry/locale';
  7. import {space} from 'sentry/styles/space';
  8. import {Mode} from 'sentry/views/explore/contexts/pageParamsContext/mode';
  9. import {useCompareAnalytics} from 'sentry/views/explore/hooks/useAnalytics';
  10. import {
  11. useMultiQueryTableAggregateMode,
  12. useMultiQueryTableSampleMode,
  13. } from 'sentry/views/explore/multiQueryMode/hooks/useMultiQueryTable';
  14. import {useMultiQueryTimeseries} from 'sentry/views/explore/multiQueryMode/hooks/useMultiQueryTimeseries';
  15. import {
  16. getQueryMode,
  17. type ReadableExploreQueryParts,
  18. useDeleteQueryAtIndex,
  19. } from 'sentry/views/explore/multiQueryMode/locationUtils';
  20. import {GroupBySection} from 'sentry/views/explore/multiQueryMode/queryConstructors/groupBy';
  21. import {SearchBarSection} from 'sentry/views/explore/multiQueryMode/queryConstructors/search';
  22. import {SortBySection} from 'sentry/views/explore/multiQueryMode/queryConstructors/sortBy';
  23. import {VisualizeSection} from 'sentry/views/explore/multiQueryMode/queryConstructors/visualize';
  24. import {MultiQueryModeChart} from 'sentry/views/explore/multiQueryMode/queryVisualizations/chart';
  25. import {MultiQueryTable} from 'sentry/views/explore/multiQueryMode/queryVisualizations/table';
  26. type Props = {
  27. index: number;
  28. query: ReadableExploreQueryParts;
  29. totalQueryRows: number;
  30. };
  31. export function QueryRow({query: queryParts, index, totalQueryRows}: Props) {
  32. const deleteQuery = useDeleteQueryAtIndex();
  33. const {groupBys, query, yAxes, sortBys} = queryParts;
  34. const mode = getQueryMode(groupBys);
  35. const aggregatesTableResult = useMultiQueryTableAggregateMode({
  36. groupBys,
  37. query,
  38. yAxes,
  39. sortBys,
  40. enabled: mode === Mode.AGGREGATE,
  41. });
  42. const spansTableResult = useMultiQueryTableSampleMode({
  43. groupBys,
  44. query,
  45. yAxes,
  46. sortBys,
  47. enabled: mode === Mode.SAMPLES,
  48. });
  49. const {timeseriesResult, canUsePreviousResults} = useMultiQueryTimeseries({
  50. index,
  51. enabled: true,
  52. });
  53. useCompareAnalytics({
  54. aggregatesTableResult,
  55. index,
  56. query: queryParts,
  57. spansTableResult,
  58. timeseriesResult,
  59. queryType: mode === Mode.AGGREGATE ? 'aggregate' : 'samples',
  60. });
  61. return (
  62. <Fragment>
  63. <QueryConstructionSection>
  64. <SearchBarSection query={queryParts} index={index} />
  65. <DropDownGrid>
  66. <VisualizeSection query={queryParts} index={index} />
  67. <GroupBySection query={queryParts} index={index} />
  68. <SortBySection query={queryParts} index={index} />
  69. <DeleteButton
  70. borderless
  71. icon={<IconDelete />}
  72. size="zero"
  73. disabled={totalQueryRows === 1}
  74. onClick={() => deleteQuery(index)}
  75. aria-label={t('Delete Query')}
  76. />
  77. </DropDownGrid>
  78. </QueryConstructionSection>
  79. <QueryVisualizationSection data-test-id={`section-visualization-${index}`}>
  80. <LazyRender containerHeight={260} withoutContainer>
  81. <MultiQueryModeChart
  82. index={index}
  83. mode={mode}
  84. query={queryParts}
  85. timeseriesResult={timeseriesResult}
  86. canUsePreviousResults={canUsePreviousResults}
  87. />
  88. <MultiQueryTable
  89. confidences={[]}
  90. mode={mode}
  91. query={queryParts}
  92. index={index}
  93. aggregatesTableResult={aggregatesTableResult}
  94. spansTableResult={spansTableResult}
  95. />
  96. </LazyRender>
  97. </QueryVisualizationSection>
  98. </Fragment>
  99. );
  100. }
  101. const QueryConstructionSection = styled('div')`
  102. display: grid;
  103. gap: ${space(1)};
  104. margin-bottom: ${space(1)};
  105. @media (min-width: ${p => p.theme.breakpoints.large}) {
  106. grid-template-columns: minmax(400px, 1fr) 1fr;
  107. }
  108. `;
  109. const DropDownGrid = styled('div')`
  110. display: grid;
  111. grid-template-columns: repeat(3, minmax(0, auto)) ${space(2)};
  112. align-items: center;
  113. gap: ${space(1)};
  114. `;
  115. const DeleteButton = styled(Button)`
  116. margin-top: ${space(2)};
  117. `;
  118. const QueryVisualizationSection = styled('div')`
  119. display: grid;
  120. grid-template-columns: 2fr 1.2fr;
  121. gap: ${space(1)};
  122. margin-bottom: ${space(2)};
  123. `;