queries.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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 {MetricWidgetQueryParams} from 'sentry/utils/metrics';
  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. }}
  53. displayType={widget.displayType}
  54. isEdit
  55. projects={selection.projects}
  56. />
  57. <MetricQueryContextMenu
  58. displayType={widget.displayType}
  59. widgetIndex={index}
  60. metricsQuery={{
  61. mri: widget.mri,
  62. query: widget.query,
  63. op: widget.op,
  64. groupBy: widget.groupBy,
  65. projects: selection.projects,
  66. datetime: selection.datetime,
  67. environments: selection.environments,
  68. title: widget.title,
  69. }}
  70. />
  71. </Row>
  72. ))}
  73. </Wrapper>
  74. );
  75. }
  76. const StyledQuerySymbol = styled(QuerySymbol)`
  77. margin-top: 10px;
  78. cursor: pointer;
  79. `;
  80. const Wrapper = styled('div')<{showQuerySymbols: boolean}>`
  81. padding-bottom: ${space(2)};
  82. display: grid;
  83. grid-template-columns: 1fr max-content;
  84. gap: ${space(1)};
  85. ${p =>
  86. p.showQuerySymbols &&
  87. `
  88. grid-template-columns: min-content 1fr max-content;
  89. `}
  90. `;
  91. const Row = styled('div')`
  92. display: contents;
  93. `;