DashboardItemForm.tsx 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /*
  2. * <<
  3. * Davinci
  4. * ==
  5. * Copyright (C) 2016 - 2017 EDP
  6. * ==
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. * >>
  19. */
  20. import React from 'react'
  21. import classnames from 'classnames'
  22. import { Form, Row, Col, Table, Input, InputNumber, Select, Steps } from 'antd'
  23. import { FormComponentProps } from 'antd/lib/form/Form'
  24. import { SortOrder, RowSelectionType } from 'antd/lib/table'
  25. import { IDashboard } from '../types'
  26. const FormItem = Form.Item
  27. const Option = Select.Option
  28. const Step = Steps.Step
  29. import SearchFilterDropdown from 'components/SearchFilterDropdown'
  30. import { IWidgetFormed } from 'app/containers/Widget/types'
  31. import ChartTypes from 'app/containers/Widget/config/chart/ChartTypes'
  32. const utilStyles = require('assets/less/util.less')
  33. interface IDashboardItemFormProps {
  34. type: string
  35. widgets: IWidgetFormed[]
  36. selectedWidgets: number[]
  37. currentDashboard?: IDashboard
  38. polling: boolean,
  39. step: number
  40. onWidgetSelect: (selectedRowKeys: any[]) => void
  41. onPollingSelect: (val: string) => any
  42. }
  43. interface IDashboardItemFormStates {
  44. tableWidget: any[]
  45. filteredWidgets: any[]
  46. pageSize: number
  47. currentPage: number
  48. screenWidth: number
  49. nameFilterValue: string
  50. nameFilterDropdownVisible: boolean
  51. tableSortedInfo: {
  52. columnKey?: string,
  53. order?: SortOrder
  54. }
  55. selectedRowKeys: any[]
  56. }
  57. export class DashboardItemForm extends React.PureComponent<IDashboardItemFormProps & FormComponentProps, IDashboardItemFormStates> {
  58. constructor (props) {
  59. super(props)
  60. this.state = {
  61. filteredWidgets: [],
  62. pageSize: 24,
  63. currentPage: 1,
  64. screenWidth: 0,
  65. tableWidget: [],
  66. nameFilterValue: '',
  67. nameFilterDropdownVisible: false,
  68. tableSortedInfo: {},
  69. selectedRowKeys: []
  70. }
  71. }
  72. public componentWillMount () {
  73. const { widgets, currentDashboard } = this.props
  74. const dashboardType = currentDashboard.type
  75. let tableWidget
  76. if (dashboardType === 2) { //
  77. tableWidget = widgets.filter((widget) => {
  78. const { selectedChart, mode } = widget.config
  79. return selectedChart === ChartTypes.Table && mode === 'chart'
  80. })
  81. } else {
  82. tableWidget = widgets
  83. }
  84. if (widgets) {
  85. this.setState({
  86. tableWidget: tableWidget.map((g) => {
  87. g.key = g.id
  88. return g
  89. })
  90. })
  91. }
  92. }
  93. public componentWillReceiveProps (nextProps) {
  94. window.addEventListener('resize', this.getScreenWidth, false)
  95. }
  96. public componentWillUnmount () {
  97. window.removeEventListener('resize', this.getScreenWidth, false)
  98. }
  99. private getScreenWidth = () => {
  100. this.setState({ screenWidth: document.documentElement.clientWidth })
  101. }
  102. private onSearchWidgetItem = (value) => {
  103. const valReg = new RegExp(value, 'i')
  104. this.setState({
  105. filteredWidgets: this.props.widgets.filter((i) => valReg.test(i.name)),
  106. currentPage: 1
  107. })
  108. }
  109. private onShowSizeChange = (currentPage, pageSize) => {
  110. this.setState({
  111. currentPage,
  112. pageSize
  113. })
  114. }
  115. private onReset = () => {
  116. this.setState({
  117. filteredWidgets: [],
  118. currentPage: 1
  119. })
  120. }
  121. private onSearchInputChange = (e) => {
  122. this.setState({
  123. nameFilterValue: e.target.value
  124. })
  125. }
  126. private onSearch = () => {
  127. const val = this.state.nameFilterValue
  128. const reg = new RegExp(val, 'gi')
  129. this.setState({
  130. nameFilterDropdownVisible: false,
  131. tableWidget: (this.props.widgets as any[]).map((record) => {
  132. const match = record.name.match(reg)
  133. if (!match) {
  134. return null
  135. }
  136. return {
  137. ...record,
  138. name: (
  139. <span>
  140. {record.name.split(reg).map((text, i) => (
  141. i > 0 ? [<span key={i} className={utilStyles.highlight}>{match[0]}</span>, text] : text
  142. ))}
  143. </span>
  144. )
  145. }
  146. }).filter((record) => !!record)
  147. })
  148. }
  149. private handleTableChange = (pagination, filters, sorter) => {
  150. this.setState({
  151. tableSortedInfo: sorter
  152. })
  153. }
  154. private onSelectChange = (selectedRowKeys) => {
  155. this.setState({
  156. selectedRowKeys
  157. }, () => {
  158. this.props.onWidgetSelect(this.state.selectedRowKeys)
  159. })
  160. }
  161. public render () {
  162. const {
  163. widgets,
  164. type,
  165. form,
  166. selectedWidgets,
  167. polling,
  168. step,
  169. onWidgetSelect,
  170. onPollingSelect,
  171. currentDashboard
  172. } = this.props
  173. const {
  174. filteredWidgets,
  175. pageSize,
  176. currentPage,
  177. screenWidth,
  178. tableWidget,
  179. nameFilterValue,
  180. nameFilterDropdownVisible,
  181. tableSortedInfo,
  182. selectedRowKeys
  183. } = this.state
  184. const dashboardType = currentDashboard.type
  185. const columns = [{
  186. title: '名称',
  187. dataIndex: 'name',
  188. key: 'name',
  189. filterDropdown: (
  190. <SearchFilterDropdown
  191. placeholder="name"
  192. value={nameFilterValue}
  193. onChange={this.onSearchInputChange}
  194. onSearch={this.onSearch}
  195. />
  196. ),
  197. filterDropdownVisible: nameFilterDropdownVisible,
  198. onFilterDropdownVisibleChange: (visible) => this.setState({
  199. nameFilterDropdownVisible: visible
  200. }),
  201. sorter: (a, b) => a.name > b.name ? -1 : 1,
  202. sortOrder: tableSortedInfo.columnKey === 'name' ? tableSortedInfo.order : void 0
  203. }, {
  204. title: '描述',
  205. dataIndex: 'description',
  206. key: 'description'
  207. }]
  208. const pagination = {
  209. simple: screenWidth < 768 || screenWidth === 768,
  210. defaultPageSize: 20,
  211. showSizeChanger: true
  212. }
  213. const rowSelection = {
  214. selectedRowKeys: selectedWidgets,
  215. onChange: this.onSelectChange,
  216. onShowSizeChange: this.onShowSizeChange,
  217. type: dashboardType === 2
  218. ? 'radio' as RowSelectionType
  219. : 'checkbox' as RowSelectionType
  220. }
  221. const stepIndicator = type === 'add'
  222. ? (
  223. <Steps current={step}>
  224. <Step title="可视化组件" />
  225. <Step title="数据更新" />
  226. <Step title="完成" />
  227. </Steps>
  228. )
  229. : ''
  230. const widgetsArr = filteredWidgets.length ? filteredWidgets : widgets
  231. const { getFieldDecorator } = form
  232. const selectWidgetStep = classnames({
  233. [utilStyles.hide]: !!step
  234. })
  235. const inputFormStep = classnames({
  236. [utilStyles.hide]: !step
  237. })
  238. const frequencyClass = classnames({
  239. [utilStyles.hide]: !polling
  240. })
  241. const isShowName = classnames({
  242. [utilStyles.hide]: !!(type === 'add')
  243. })
  244. return (
  245. <Form>
  246. <Row className={utilStyles.formStepArea}>
  247. <Col span={24}>
  248. {stepIndicator}
  249. </Col>
  250. </Row>
  251. <Row gutter={20} className={selectWidgetStep}>
  252. <Table
  253. dataSource={tableWidget}
  254. columns={columns}
  255. pagination={pagination}
  256. onChange={this.handleTableChange}
  257. rowSelection={rowSelection}
  258. />
  259. </Row>
  260. <div className={inputFormStep}>
  261. <Row gutter={8}>
  262. <Col sm={8}>
  263. <FormItem className={utilStyles.hide}>
  264. {getFieldDecorator('id')(
  265. <Input />
  266. )}
  267. </FormItem>
  268. <FormItem
  269. label="组件别名"
  270. labelCol={{span: 10}}
  271. wrapperCol={{span: 14}}
  272. className={isShowName}
  273. >
  274. {getFieldDecorator('alias', {})(
  275. <Input/>
  276. )}
  277. </FormItem>
  278. <FormItem
  279. label="数据刷新模式"
  280. labelCol={{span: 10}}
  281. wrapperCol={{span: 14}}
  282. >
  283. {getFieldDecorator('polling', {
  284. initialValue: polling ? 'true' : 'false'
  285. })(
  286. <Select onSelect={onPollingSelect}>
  287. <Option value="false">手动刷新</Option>
  288. <Option value="true">定时刷新</Option>
  289. </Select>
  290. )}
  291. </FormItem>
  292. </Col>
  293. <Col sm={4} className={frequencyClass}>
  294. <FormItem
  295. label="时长"
  296. labelCol={{span: 12}}
  297. wrapperCol={{span: 12}}
  298. >
  299. {getFieldDecorator('frequency', {
  300. rules: [{
  301. required: true,
  302. message: '不能为空'
  303. }],
  304. initialValue: 60
  305. })(
  306. <InputNumber min={1} placeholder="秒" />
  307. )}
  308. </FormItem>
  309. </Col>
  310. </Row>
  311. </div>
  312. </Form>
  313. )
  314. }
  315. }
  316. export default Form.create<IDashboardItemFormProps & FormComponentProps>()(DashboardItemForm)