index.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import 'react-grid-layout/css/styles.css';
  2. import 'react-resizable/css/styles.css';
  3. import GridLayout, {WidthProvider} from 'react-grid-layout';
  4. import styled from '@emotion/styled';
  5. import {defined} from 'sentry/utils';
  6. import {uniqueId} from 'sentry/utils/guid';
  7. import {
  8. assignDefaultLayout,
  9. calculateColumnDepths,
  10. } from 'sentry/views/dashboards/layoutUtils';
  11. import type {WidgetLayout, WidgetPreview} from 'sentry/views/dashboards/types';
  12. import {DisplayType} from 'sentry/views/dashboards/types';
  13. import WidgetArea from './chartPreviews/area';
  14. import WidgetBar from './chartPreviews/bar';
  15. import WidgetLine from './chartPreviews/line';
  16. import WidgetBigNumber from './chartPreviews/number';
  17. import WidgetTable from './chartPreviews/table';
  18. function miniWidget(displayType: DisplayType): () => JSX.Element {
  19. switch (displayType) {
  20. case DisplayType.BAR:
  21. return WidgetBar;
  22. case DisplayType.AREA:
  23. case DisplayType.TOP_N:
  24. return WidgetArea;
  25. case DisplayType.BIG_NUMBER:
  26. return WidgetBigNumber;
  27. case DisplayType.TABLE:
  28. return WidgetTable;
  29. case DisplayType.LINE:
  30. default:
  31. return WidgetLine;
  32. }
  33. }
  34. type Props = {
  35. widgetPreview: WidgetPreview[];
  36. };
  37. function GridPreview({widgetPreview}: Props) {
  38. const definedLayouts = widgetPreview
  39. .map(({layout}) => layout)
  40. .filter((layout): layout is WidgetLayout => defined(layout));
  41. const columnDepths = calculateColumnDepths(definedLayouts);
  42. const renderPreview = assignDefaultLayout(widgetPreview, columnDepths);
  43. return (
  44. <StyledGridLayout
  45. cols={6}
  46. rowHeight={40}
  47. margin={[4, 4]}
  48. isResizable={false}
  49. isDraggable={false}
  50. useCSSTransforms={false}
  51. measureBeforeMount
  52. >
  53. {renderPreview.map(({displayType, layout}) => {
  54. const Preview = miniWidget(displayType);
  55. return (
  56. <Chart key={uniqueId()} data-grid={{...layout}}>
  57. <PreviewWrapper>
  58. <Preview />
  59. </PreviewWrapper>
  60. </Chart>
  61. );
  62. })}
  63. </StyledGridLayout>
  64. );
  65. }
  66. export default GridPreview;
  67. const PreviewWrapper = styled('div')`
  68. padding: 20px 8px 4px 12px;
  69. height: 100%;
  70. width: 100%;
  71. overflow: hidden;
  72. `;
  73. // ::before is the widget title and ::after is the border
  74. const Chart = styled('div')`
  75. background: white;
  76. position: relative;
  77. &::before {
  78. content: '';
  79. position: absolute;
  80. left: 12px;
  81. top: 10px;
  82. width: max(30px, 30%);
  83. height: 4px;
  84. background-color: #d4d1ec;
  85. border-radius: 8px;
  86. }
  87. &::after {
  88. content: '';
  89. position: absolute;
  90. left: 2px;
  91. top: 2px;
  92. width: 100%;
  93. height: 100%;
  94. border: 2px solid #444674;
  95. }
  96. `;
  97. const StyledGridLayout = styled(WidthProvider(GridLayout))`
  98. margin: -4px;
  99. `;