configForm.jsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. import React from 'react'
  2. import { connect } from 'dva'
  3. import { Form, Input, Divider, Button, Icon, Collapse, Spin } from 'antd'
  4. class ConfigForm extends React.Component {
  5. constructor(props) {
  6. super(props);
  7. this.state = {
  8. selectedDataSource: null,
  9. selectedColumn: null,
  10. activeKey: [],
  11. editing: false
  12. };
  13. }
  14. addRelationColumn = () => {
  15. const { dispatch } = this.props;
  16. dispatch({ type: 'dashboardDesigner/addRelationColumn' });
  17. }
  18. deleteRelationColumn = (e) => {
  19. const { dispatch } = this.props;
  20. const code = e.target.dataset.code;
  21. dispatch({ type: 'dashboardDesigner/deleteRelationColumn', code });
  22. }
  23. render() {
  24. const { dashboardDesigner, dispatch } = this.props;
  25. const { activeKey, editing, selectedDataSource, selectedColumn } = this.state;
  26. const { relationColumns, dataSources, columnFetching } = dashboardDesigner;
  27. return <Form className='config-form'>
  28. <Divider>自定义过滤字段</Divider>
  29. <div className='filtercolumns'>
  30. <Collapse key='filtercolumnscollapse' activeKey={activeKey} onChange={k => {
  31. this.setState({
  32. selectedDataSource: null,
  33. selectedColumn: null,
  34. activeKey: k[k.length - 1], // 保持只有一个展开项
  35. });
  36. }}>
  37. {
  38. relationColumns.map((r, ri) => (
  39. <Collapse.Panel
  40. key={r.code}
  41. disabled={editing}
  42. header={<Form.Item className='filtercolumn-name' label='名称' labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
  43. <Input size='small' value={r.name}
  44. onChange={(e) => {
  45. dispatch({ type: 'dashboardDesigner/setRelationColumn', code: r.code, relationColumn: { ...r, name: e.target.value } });
  46. }} onFocus={() => {
  47. this.setState({
  48. editing: true,
  49. })
  50. }} onBlur={() => {
  51. this.setState({
  52. editing: false
  53. })
  54. }}/>
  55. </Form.Item>}
  56. >
  57. {(dataSources.length > 0 ? <div className='filtercolumn-relation'>
  58. {columnFetching && <div className='loading'>
  59. <Spin />
  60. </div>}
  61. <div className='datasources'>
  62. { dataSources.map((d, di) => (
  63. <Button
  64. className='datasource'
  65. key={d.code}
  66. type={!!selectedDataSource && selectedDataSource.code === d.code ? 'primary' : 'default'}
  67. onClick={() => {
  68. this.setState({
  69. selectedDataSource: {
  70. code: d.code,
  71. name: d.name
  72. },
  73. selectedColumn: null
  74. });
  75. dispatch({ type: 'dashboardDesigner/remoteGetColumns', dataSourceCode: d.code });
  76. }}
  77. >
  78. <span className='label'>{d.name}</span>
  79. {r.relations.findIndex(r => r.dataSource.code === d.code) !== -1 && <Icon type='check-circle' theme={r.relations[0].dataSource.code === d.code ? 'filled' : 'outlined'} />}
  80. </Button>
  81. )) }
  82. </div>
  83. <div className='columns'>
  84. { !!selectedDataSource &&
  85. !!dataSources.find(d => d.code === selectedDataSource.code) &&
  86. !!dataSources.find(d => d.code === selectedDataSource.code).columns &&
  87. dataSources.find(d => d.code === selectedDataSource.code).columns.filter(c => {
  88. if(!!r.relations[0]) {
  89. // 选中的不是第一个
  90. if(r.relations[0].dataSource.code !== selectedDataSource.code) {
  91. // 只能选用同类型的列
  92. return c.type === r.relations[0].column.type;
  93. }else {
  94. return true;
  95. }
  96. }else {
  97. return true;
  98. }
  99. }).map(c => (
  100. <Button
  101. className='column'
  102. type={!!selectedColumn && selectedColumn.name === c.name ? 'primary' : 'default'}
  103. key={c.name}
  104. onClick={() => {
  105. this.setState({
  106. selectedColumn: {
  107. name: c.name,
  108. label: c.label
  109. }
  110. }, () => {
  111. let { selectedColumn } = this.state;
  112. const { relations } = r;
  113. let idx = relations.findIndex(r => r.dataSource.code === selectedDataSource.code);
  114. if(idx === -1){
  115. relations.push({
  116. dataSource: {
  117. code: selectedDataSource.code,
  118. name: selectedDataSource.name
  119. },
  120. column: {
  121. label: c.label,
  122. name: c.name,
  123. type: c.type
  124. }
  125. });
  126. }else {
  127. let cr = relations[idx];
  128. if(cr.column.name === selectedColumn.name) {
  129. relations.splice(idx, 1);
  130. }else {
  131. relations[idx] = {
  132. dataSource: {
  133. code: selectedDataSource.code,
  134. name: selectedDataSource.name
  135. },
  136. column: {
  137. code: c.code,
  138. name: c.name,
  139. type: c.type
  140. }
  141. };
  142. }
  143. }
  144. let index = relationColumns.findIndex(rc => rc.code === r.code);
  145. relationColumns[index] = { ...r, relations };
  146. dispatch({ type: 'dashboardDesigner/setField', name: 'relationColumns', value: relationColumns });
  147. });
  148. }}
  149. >
  150. <span className='label'>{c.label}</span>
  151. {r.relations.findIndex(r => r.dataSource.code === selectedDataSource.code) !== -1 && r.relations[r.relations.findIndex(r => r.dataSource.code === selectedDataSource.code)].column.name === c.name && <Icon type='check-circle' theme={r.relations[0].column.name === c.name ? 'filled' : 'outlined'} />}
  152. </Button>
  153. )) }
  154. </div>
  155. </div> : <div className='filtercolumn-empty'>
  156. 无关联数据源
  157. </div>)}
  158. <div className='filtercolumn-delete'>
  159. <Button type='danger' className='delbtn' data-code={r.code} onClick={this.deleteRelationColumn}>
  160. <Icon type='delete' theme='outlined' />删除
  161. </Button>
  162. </div>
  163. </Collapse.Panel>
  164. ))
  165. }
  166. </Collapse>
  167. <div className='bottom-btns'>
  168. <Button className='addbtn' onClick={this.addRelationColumn}>
  169. <Icon type='plus' theme='outlined' />添加
  170. </Button>
  171. </div>
  172. </div>
  173. </Form>
  174. }
  175. }
  176. export default connect(({ present: { dashboardDesigner } }) => ({ dashboardDesigner }))(ConfigForm);