queries.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import {useCallback, useLayoutEffect} from 'react';
  2. import styled from '@emotion/styled';
  3. import * as echarts from 'echarts/core';
  4. import {t} from 'sentry/locale';
  5. import {space} from 'sentry/styles/space';
  6. import type {MetricWidgetQueryParams} from 'sentry/utils/metrics/types';
  7. import usePageFilters from 'sentry/utils/usePageFilters';
  8. import {DDM_CHART_GROUP} from 'sentry/views/ddm/constants';
  9. import {useDDMContext} from 'sentry/views/ddm/context';
  10. import {MetricQueryContextMenu} from 'sentry/views/ddm/contextMenu';
  11. import {QueryBuilder} from 'sentry/views/ddm/queryBuilder';
  12. import {QuerySymbol} from 'sentry/views/ddm/querySymbol';
  13. export function Queries() {
  14. const {
  15. widgets,
  16. updateWidget,
  17. setSelectedWidgetIndex,
  18. showQuerySymbols,
  19. selectedWidgetIndex,
  20. } = useDDMContext();
  21. const {selection} = usePageFilters();
  22. // Make sure all charts are connected to the same group whenever the widgets definition changes
  23. useLayoutEffect(() => {
  24. echarts.connect(DDM_CHART_GROUP);
  25. }, [widgets]);
  26. const handleChange = useCallback(
  27. (index: number, widget: Partial<MetricWidgetQueryParams>) => {
  28. updateWidget(index, widget);
  29. },
  30. [updateWidget]
  31. );
  32. return (
  33. <Wrapper showQuerySymbols={showQuerySymbols}>
  34. {widgets.map((widget, index) => (
  35. <Row key={index} onFocusCapture={() => setSelectedWidgetIndex(index)}>
  36. {showQuerySymbols && (
  37. <StyledQuerySymbol
  38. index={index}
  39. isSelected={index === selectedWidgetIndex}
  40. onClick={() => setSelectedWidgetIndex(index)}
  41. role="button"
  42. aria-label={t('Select query')}
  43. />
  44. )}
  45. <QueryBuilder
  46. onChange={data => handleChange(index, data)}
  47. metricsQuery={{
  48. mri: widget.mri,
  49. op: widget.op,
  50. groupBy: widget.groupBy,
  51. title: widget.title,
  52. query: widget.query,
  53. }}
  54. displayType={widget.displayType}
  55. isEdit
  56. projects={selection.projects}
  57. />
  58. <MetricQueryContextMenu
  59. displayType={widget.displayType}
  60. widgetIndex={index}
  61. metricsQuery={{
  62. mri: widget.mri,
  63. query: widget.query,
  64. op: widget.op,
  65. groupBy: widget.groupBy,
  66. projects: selection.projects,
  67. datetime: selection.datetime,
  68. environments: selection.environments,
  69. title: widget.title,
  70. }}
  71. />
  72. </Row>
  73. ))}
  74. </Wrapper>
  75. );
  76. }
  77. const StyledQuerySymbol = styled(QuerySymbol)`
  78. margin-top: 10px;
  79. cursor: pointer;
  80. `;
  81. const Wrapper = styled('div')<{showQuerySymbols: boolean}>`
  82. padding-bottom: ${space(2)};
  83. display: grid;
  84. grid-template-columns: 1fr max-content;
  85. gap: ${space(1)};
  86. ${p =>
  87. p.showQuerySymbols &&
  88. `
  89. grid-template-columns: min-content 1fr max-content;
  90. `}
  91. `;
  92. const Row = styled('div')`
  93. display: contents;
  94. `;