index.tsx 2.8 KB

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