index.tsx 2.7 KB

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