scratchpad.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import styled from '@emotion/styled';
  2. import * as echarts from 'echarts/core';
  3. import {Button} from 'sentry/components/button';
  4. import Panel from 'sentry/components/panels/panel';
  5. import {IconAdd} from 'sentry/icons';
  6. import {space} from 'sentry/styles/space';
  7. import usePageFilters from 'sentry/utils/usePageFilters';
  8. import {DDM_CHART_GROUP, MIN_WIDGET_WIDTH} from 'sentry/views/ddm/constants';
  9. import {MetricWidget, useMetricWidgets} from './widget';
  10. export function MetricScratchpad() {
  11. const {widgets, onChange, addWidget} = useMetricWidgets();
  12. const {selection} = usePageFilters();
  13. const Wrapper =
  14. widgets.length === 1 ? StyledSingleWidgetWrapper : StyledMetricDashboard;
  15. echarts.connect(DDM_CHART_GROUP);
  16. return (
  17. <Wrapper>
  18. {widgets.map(widget => (
  19. <MetricWidget
  20. key={widget.position}
  21. widget={{
  22. ...widget,
  23. onChange: data => {
  24. onChange(widget.position, data);
  25. },
  26. }}
  27. datetime={selection.datetime}
  28. projects={selection.projects}
  29. environments={selection.environments}
  30. />
  31. ))}
  32. <AddWidgetPanel onClick={addWidget}>
  33. <Button icon={<IconAdd isCircled />}>Add widget</Button>
  34. </AddWidgetPanel>
  35. </Wrapper>
  36. );
  37. }
  38. const StyledMetricDashboard = styled('div')`
  39. display: grid;
  40. grid-template-columns: repeat(3, minmax(${MIN_WIDGET_WIDTH}px, 1fr));
  41. gap: ${space(2)};
  42. @media (max-width: ${props => props.theme.breakpoints.xxlarge}) {
  43. grid-template-columns: repeat(2, minmax(${MIN_WIDGET_WIDTH}px, 1fr));
  44. }
  45. @media (max-width: ${props => props.theme.breakpoints.xlarge}) {
  46. grid-template-columns: repeat(1, minmax(${MIN_WIDGET_WIDTH}px, 1fr));
  47. }
  48. grid-auto-rows: 1fr;
  49. `;
  50. const StyledSingleWidgetWrapper = styled('div')`
  51. display: grid;
  52. grid-template-columns: minmax(${MIN_WIDGET_WIDTH}px, 90%) minmax(180px, 10%);
  53. @media (max-width: ${props => props.theme.breakpoints.xlarge}) {
  54. grid-template-columns: repeat(1, minmax(${MIN_WIDGET_WIDTH}px, 1fr));
  55. }
  56. gap: ${space(2)};
  57. grid-auto-rows: 1fr;
  58. `;
  59. const AddWidgetPanel = styled(Panel)`
  60. width: 100%;
  61. height: 100%;
  62. margin-bottom: 0;
  63. padding: ${space(4)};
  64. font-size: ${p => p.theme.fontSizeExtraLarge};
  65. display: flex;
  66. justify-content: center;
  67. align-items: center;
  68. border: 1px dashed ${p => p.theme.border};
  69. &:hover {
  70. background-color: ${p => p.theme.backgroundSecondary};
  71. cursor: pointer;
  72. }
  73. `;