chooseDataSourceBox.jsx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. import React from 'react'
  2. import { Modal, Table, Radio, message, Row, Col } from 'antd'
  3. import { connect } from 'dva'
  4. import './chooseDataSourceBox.less'
  5. import { dateFormat } from '../../utils/baseUtils'
  6. import ListFilter from '../common/listFilter/index'
  7. class ChooseDataSourceBox extends React.Component {
  8. constructor(props) {
  9. super(props);
  10. this.state = {
  11. filterItem: { name: 'name', label: '名称', type: 'string' },
  12. filterLabel: '',
  13. selectedRecord: null,
  14. screenWidth: document.documentElement.clientWidth || document.body.clientWidth,
  15. screenHeight: document.documentElement.clientHeight || document.body.clientHeight
  16. }
  17. }
  18. componentDidMount() {
  19. const { dispatch } = this.props;
  20. dispatch({ type: 'dataSource/fetchList' });
  21. window.addEventListener('resize', this.onWindowResize);
  22. }
  23. componentWillUnmount() {
  24. window.removeEventListener('resize', this.onWindowResize);
  25. }
  26. onWindowResize = () => {
  27. this.setState({
  28. screenWidth: document.documentElement.clientWidth || document.body.clientWidth,
  29. screenHeight: document.documentElement.clientHeight || document.body.clientHeight
  30. });
  31. }
  32. changeSelected = (record) => {
  33. this.setState({
  34. selectedRecord: Object.assign({}, record)
  35. });
  36. }
  37. okHandler = (model) => {
  38. const { selectedRecord } = this.state;
  39. const { dispatch, hideBox } = this.props;
  40. if(selectedRecord) {
  41. dispatch({ type: 'chartDesigner/remoteQucikAdd', dataSource: selectedRecord });
  42. hideBox();
  43. }else {
  44. message.warning('未选中数据源');
  45. }
  46. }
  47. onSearch = (list) => {
  48. const { filterItem, filterLabel: stateFilterLabel } = this.state;
  49. const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
  50. let filterLabel = stateFilterLabel ? (stateFilterLabel + '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') : ''; // 添加转义符号
  51. let filterReg = new RegExp('('+ filterLabel +'){1}', 'ig');
  52. return list.map(l => {
  53. let o = Object.assign({}, l);
  54. if(filterItem.type === 'date') {
  55. if(filterLabel===""){
  56. return o;
  57. }else if(filterLabel.indexOf('#')>-1){
  58. let start = filterLabel.split('#')[0]
  59. let end = filterLabel.split('#')[1]
  60. let nowTime = o[filterItem.name].getTime();
  61. if(nowTime>=start && nowTime<=end){
  62. return o;
  63. }
  64. return null
  65. }else{
  66. return null
  67. }
  68. }else {
  69. let arr = filterItem.name.split('.');
  70. let v = o;
  71. for(let i = 0; i < arr.length; i++) {
  72. v = v[arr[i]]
  73. }
  74. return ((v + '').search(filterReg) > -1) ? o : null
  75. }
  76. }).filter(a => a!==null);
  77. }
  78. render() {
  79. const { dataSource, visibleChooseDataSourceBox, hideBox } = this.props
  80. const { filterItem, filterLabel: stateFilterLabel, selectedRecord, screenWidth, screenHeight } = this.state;
  81. const tableBodyWidth = screenWidth * 0.8 - 10 - 10 - 18;
  82. const tableBodyHeight = screenHeight * 0.8 - 65 - 53 - 38 - 130;
  83. const tableRowHeight = 38;
  84. const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
  85. let filterLabel = stateFilterLabel ? (stateFilterLabel + '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') : ''; // 添加转义符号
  86. const columns = [{
  87. title: '选择',
  88. key: 'selected',
  89. width: 50,
  90. render: (text, record) => {
  91. return <Radio checked={selectedRecord ? selectedRecord.code === record.code : false}/>
  92. }
  93. }, {
  94. title: '名称',
  95. dataIndex: 'name',
  96. key: 'name',
  97. width: 200,
  98. render: (text, record) => {
  99. return <div className='datasource-name'>
  100. <div className={`datasource-type type-${record.type.key}`}></div>
  101. <div>
  102. <span>
  103. { (filterItem.name === 'name' && filterLabel) ?
  104. (text.split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
  105. return (
  106. fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
  107. <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
  108. fragment
  109. )
  110. }
  111. )) : text
  112. }
  113. </span>
  114. </div>
  115. </div>
  116. }
  117. }, {
  118. title: '数据链接',
  119. dataIndex: 'dbConfig.name',
  120. key: 'dbConfig.name',
  121. width: 100
  122. }, {
  123. title: '创建人',
  124. dataIndex: 'creatorName',
  125. key: 'creatorName',
  126. width: 100,
  127. render: (text, record) => {
  128. return <div className='datasource-name'>
  129. <div className={`datasource-type type-${record.type.key}`}></div>
  130. <div>
  131. <span>
  132. { (filterItem.name === 'creatorName' && filterLabel) ?
  133. (text.split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
  134. return (
  135. fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
  136. <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
  137. fragment
  138. )
  139. }
  140. )) : text
  141. }
  142. </span>
  143. </div>
  144. </div>
  145. }
  146. }, {
  147. title: '创建时间',
  148. dataIndex: 'createTime',
  149. key: 'createTime',
  150. width: 120,
  151. render: (text) => dateFormat(new Date(text), 'yyyy-MM-dd')
  152. }, {
  153. title: '说明',
  154. dataIndex: 'description',
  155. key: 'description',
  156. width: 200,
  157. render: (text, record) => {
  158. return (
  159. <span>
  160. { (filterItem.name === 'description' && filterLabel) ?
  161. ((text || '').split(new RegExp(`(${filterLabel})`, 'i')).map((fragment, i) => {
  162. return (
  163. fragment.toLowerCase().replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') === filterLabel.toLowerCase() ?
  164. <span key={i} style={{fontWeight: 'bold', color: 'red'}} className="highlight">{fragment}</span> :
  165. fragment
  166. )
  167. }
  168. )) : text
  169. }
  170. </span>
  171. )
  172. }
  173. }];
  174. return (
  175. <Modal
  176. className='choosedatasource-box'
  177. title='选择数据源'
  178. visible={visibleChooseDataSourceBox}
  179. onOk={this.okHandler}
  180. onCancel={hideBox}
  181. maskClosable={false}
  182. destroyOnClose={true}
  183. >
  184. <div>
  185. <Row type='flex' justify='end'>
  186. <Col style={{ padding: '8px' }}>
  187. <ListFilter
  188. modelName={null}
  189. model={{
  190. filterItems: dataSource.filterItems,
  191. filterItem, // 已选过滤字段
  192. filterLabel: stateFilterLabel,
  193. }}
  194. onChangeFilterItem={(filterItem) => {
  195. this.setState({
  196. filterItem
  197. });
  198. }}
  199. onChangeFilterValue={(filterLabel) => {
  200. this.setState({
  201. filterLabel
  202. });
  203. }}
  204. />
  205. </Col>
  206. </Row>
  207. <Table
  208. className='choosedatasource-table'
  209. columns={columns}
  210. dataSource={this.onSearch(dataSource.list)}
  211. size='small'
  212. scroll={{ x: columns ? columns.length * 100 : tableBodyWidth, y: tableBodyHeight }}
  213. pagination={{ defaultPageSize: Math.floor(tableBodyHeight/tableRowHeight) || 10 }}
  214. onRow={(record) => {
  215. return {
  216. onClick: () => {
  217. this.changeSelected(record);
  218. }
  219. };
  220. }}
  221. />
  222. </div>
  223. </Modal>
  224. )
  225. }
  226. }
  227. function mapStateToProps({ present: { dataSource } }) {
  228. return { dataSource: dataSource };
  229. }
  230. export default connect(mapStateToProps)(ChooseDataSourceBox)