viewLayout.jsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import React from "react"
  2. import "./viewLayout.less"
  3. import ReactGridLayout from 'react-grid-layout'
  4. import { Modal } from 'antd'
  5. import { connect } from 'dva'
  6. import EmptyContent from '../common/emptyContent/index'
  7. import DataPreview from '../common/dataPreview/dataPreview'
  8. import ViewLayoutItem from './viewLayoutItem';
  9. class ViewLayout extends React.PureComponent {
  10. constructor(props) {
  11. super(props);
  12. this.state = {
  13. previewItem: null,
  14. visiblePreviewBox: false,
  15. screenWidth: document.documentElement.clientWidth || document.body.clientWidth,
  16. screenHeight: document.documentElement.clientHeight || document.body.clientHeight,
  17. editingKey: null,
  18. richTextReadOnly: false,
  19. };
  20. }
  21. componentDidMount() {
  22. window.addEventListener('resize', this.onWindowResize);
  23. }
  24. componentWillUnmount() {
  25. window.removeEventListener('resize', this.onWindowResize);
  26. }
  27. onWindowResize = () => {
  28. this.setState({
  29. screenWidth: document.documentElement.clientWidth || document.body.clientWidth,
  30. screenHeight: document.documentElement.clientHeight || document.body.clientHeight
  31. });
  32. }
  33. createElement = (item, isPreview, reload, contentSize, esMobile) => {
  34. const { code, layout } = item;
  35. return <div key={code} data-grid={esMobile ? { x:0, y:50, w:12, h:8, minW: 12, maxW:12, minH:8, maxH:8 } : layout} style={{ height: '100%' }}>
  36. <ViewLayoutItem
  37. item={item}
  38. esMobile={esMobile}
  39. isPreview={isPreview}
  40. reload={reload}
  41. showPreviewBox={this.showPreviewBox}
  42. hidePreviewBox={this.hidePreviewBox}
  43. contentSize={contentSize}
  44. />
  45. </div>
  46. }
  47. onLayoutChange = (layout) => {
  48. const { dispatch } = this.props;
  49. if(!(layout.length === 1 && layout[0].i === 'default-chartview')) {
  50. dispatch({ type: 'dashboardDesigner/changeLayout', layout });
  51. window.clearTimeout(this.layoutChangeKey);
  52. this.layoutChangeKey = window.setTimeout(() => {
  53. var e = document.createEvent("Event");
  54. e.initEvent("resize", true, true);
  55. window.dispatchEvent(e);
  56. }, 500);
  57. }
  58. }
  59. onResize = (Layout, oldItem, newItem, placeholder, e, element) => {
  60. const viewContentRef = this.viewContentRef;
  61. let box = viewContentRef.getBoundingClientRect();
  62. let bottomY = box.y + box.height;
  63. if(bottomY - e.clientY <= 5) { // 鼠标接近容器底部时滚动条滚到底
  64. window.clearTimeout(this.scrollToBottomKey);
  65. this.scrollToBottomKey = window.setTimeout(this.scrollToBottom, 50);
  66. }
  67. }
  68. scrollToBottom = () => {
  69. const viewContentRef = this.viewContentRef;
  70. viewContentRef.scrollTo && viewContentRef.scrollTo(0, viewContentRef.scrollHeight - viewContentRef.clientHeight)
  71. }
  72. showPreviewBox = (item) => {
  73. this.setState({
  74. previewItem: item,
  75. visiblePreviewBox: true,
  76. lastViewCode: item.code,
  77. lastPage: item.chartOption ? item.chartOption.page : 1,
  78. lastPageSize: item.chartOption ? item.chartOption.pageSize : 0,
  79. });
  80. }
  81. hidePreviewBox = () => {
  82. const { dashboardDesigner, dispatch } = this.props;
  83. const { lastViewCode, lastPage, lastPageSize } = this.state;
  84. let item = dashboardDesigner.items.find(x => x.code === lastViewCode)
  85. this.setState({
  86. previewItem: null,
  87. visiblePreviewBox: false
  88. });
  89. if(item.chartOption) {
  90. dispatch({ type: 'setItemFields', code: lastViewCode, fields: [
  91. { name: 'chartOption', value: { ...item.chartOption, page: lastPage, pageSize: lastPageSize } }
  92. ] });
  93. }
  94. }
  95. render() {
  96. const { dashboardDesigner, contentSize, esMobile, dispatch } = this.props;
  97. const { editingKey } = this.state;
  98. const { editMode, minLayoutHeight, layoutMargin, theme: themeName } = dashboardDesigner;
  99. const { visiblePreviewBox, previewItem } = this.state;
  100. const children = dashboardDesigner.items.map((item) => this.createElement(item, false, !item.chartOption, contentSize, esMobile));
  101. return (<div className={`dashboard-viewcontent ${themeName}`} ref={node => this.viewContentRef = node}>
  102. <ReactGridLayout
  103. width={ contentSize.width }
  104. autoSize={true}
  105. cols={12}
  106. margin = {editMode ? layoutMargin : layoutMargin}
  107. rowHeight = {minLayoutHeight}
  108. isDraggable={editMode && !editingKey}
  109. isResizable={editMode && !editingKey}
  110. draggableHandle='.mover'
  111. onLayoutChange={this.onLayoutChange}
  112. onResize={this.onResize}
  113. verticalCompact={true}
  114. compactType='vertical'
  115. >
  116. {(children.length === 0) ? <div key='default-chartview' className='default-chartview' data-grid={{ x: 0, y: 0, w: 12, h: 2, minW: 12, maxW: 12, minH: 2, maxH: 2, static: true }}>
  117. <EmptyContent />
  118. </div> : children}
  119. </ReactGridLayout>
  120. {visiblePreviewBox && previewItem.chartType === 'dataView' && <DataPreview
  121. modalClassName={`${themeName} ${esMobile ? 'mobile' : ''}`}
  122. title={previewItem.name}
  123. visibleBox={visiblePreviewBox}
  124. hideBox={this.hidePreviewBox}
  125. fetchFunction={(page, pageSize) => {
  126. dispatch({ type: 'dashboardDesigner/fetchDataList', item: previewItem, mandatory: true, page, pageSize });
  127. }}
  128. />}
  129. {visiblePreviewBox && previewItem.chartType !== 'dataView' && <Modal
  130. className={`previewbox ${themeName} ${esMobile ? 'mobile' : ''}`}
  131. width={'100%'}
  132. height={'100%'}
  133. visible={visiblePreviewBox}
  134. onCancel={this.hidePreviewBox}
  135. footer={null}
  136. keyboard={true}
  137. maskClosable={true}
  138. >
  139. {!!previewItem && this.createElement(dashboardDesigner.items.find(item => item.code === previewItem.code), true, false, {width: document.body.offsetWidth-36*2, height:document.body.offsetHeight - 40}, esMobile)}
  140. </Modal>}
  141. </div>);
  142. }
  143. }
  144. export default connect(({ present: { main, dashboardDesigner } }) => ({ main, dashboardDesigner }))(ViewLayout);