WidgetSelector.tsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. import React from 'react'
  2. import classnames from 'classnames'
  3. import { iconMapping } from './util'
  4. import { IWidgetFormed } from '../types'
  5. import { Icon, Row, Col, Checkbox, Pagination, Input } from 'antd'
  6. const Search = Input.Search
  7. const styles = require('../Widget.less')
  8. export interface IWidgetSelectorProps {
  9. className?: string
  10. widgets: IWidgetFormed[]
  11. multiple: boolean
  12. widgetsSelected: IWidgetFormed[]
  13. onWidgetsSelect: (widgets: IWidgetFormed[]) => void
  14. }
  15. interface IWidgetSelectorStates {
  16. screenWidth: number
  17. kwWidget: string
  18. pageSize: number
  19. currentPage: number
  20. showSelected: false
  21. }
  22. export class WidgetSelector extends React.Component<IWidgetSelectorProps, IWidgetSelectorStates> {
  23. constructor (props) {
  24. super(props)
  25. this.state = {
  26. screenWidth: 0,
  27. kwWidget: '',
  28. pageSize: 24,
  29. currentPage: 1,
  30. showSelected: false
  31. }
  32. }
  33. public componentWillMount () {
  34. this.getScreenWidth()
  35. window.addEventListener('resize', this.getScreenWidth, false)
  36. }
  37. public componentWillUnmount () {
  38. window.removeEventListener('resize', this.getScreenWidth, false)
  39. }
  40. private getScreenWidth = () => {
  41. this.setState({ screenWidth: document.documentElement.clientWidth })
  42. }
  43. private onChange = (page) => {
  44. this.setState({
  45. currentPage: page
  46. })
  47. }
  48. private onSearchWidgetItem = (value) => {
  49. this.setState({
  50. kwWidget: value
  51. })
  52. }
  53. private getWidgets () {
  54. const {
  55. widgets,
  56. widgetsSelected
  57. } = this.props
  58. const {
  59. kwWidget,
  60. showSelected
  61. } = this.state
  62. if (!Array.isArray(widgets)) {
  63. return []
  64. }
  65. const reg = new RegExp(kwWidget, 'i')
  66. const filteredWidgets = widgets.filter((w) => {
  67. let valid = true
  68. if (showSelected) {
  69. valid = valid && widgetsSelected.findIndex((ws) => ws.id === w.id) >= 0
  70. }
  71. if (valid && kwWidget) {
  72. valid = valid && reg.test(w.name)
  73. }
  74. return valid
  75. })
  76. return filteredWidgets
  77. }
  78. private onShowSizeChange = (current, pageSize) => {
  79. this.setState({
  80. currentPage: current,
  81. pageSize
  82. })
  83. }
  84. private onWidgetSelect = (w) => (e) => {
  85. const {
  86. multiple,
  87. onWidgetsSelect
  88. } = this.props
  89. let newWidgetsSelected
  90. if (!multiple) {
  91. newWidgetsSelected = [w]
  92. } else {
  93. const {
  94. widgetsSelected
  95. } = this.props
  96. const idx = widgetsSelected.findIndex((ws) => ws.id === w.id)
  97. newWidgetsSelected = [...widgetsSelected]
  98. idx < 0 ? newWidgetsSelected.push(w) : newWidgetsSelected.splice(idx, 1)
  99. if (widgetsSelected.length <= 0 && this.state.showSelected) {
  100. this.setState({ showSelected: false })
  101. }
  102. }
  103. onWidgetsSelect(newWidgetsSelected)
  104. }
  105. private onShowTypeChange = (e) => {
  106. this.setState({
  107. showSelected: e.target.checked,
  108. currentPage: 1
  109. })
  110. }
  111. public render () {
  112. const {
  113. className,
  114. widgetsSelected
  115. } = this.props
  116. const {
  117. screenWidth,
  118. pageSize,
  119. currentPage,
  120. showSelected
  121. } = this.state
  122. const widgetsFiltered = this.getWidgets()
  123. const startCol = (currentPage - 1) * pageSize
  124. const endCol = Math.min(currentPage * pageSize, widgetsFiltered.length)
  125. const widgetsCurrent = widgetsFiltered.slice(startCol, endCol)
  126. const widgetsList = widgetsCurrent.map((w, idx) => {
  127. const widgetType = w.type
  128. const widgetClassName = classnames({
  129. [styles.widget]: true,
  130. [styles.selector]: true,
  131. [styles.selected]: w.id === 1
  132. })
  133. const checkmark = widgetsSelected.findIndex((ws) => ws.id === w.id) >= 0
  134. ? (
  135. <div className={styles.checkmark}>
  136. <Icon type="check" />
  137. </div>
  138. )
  139. : ''
  140. return (
  141. <Col lg={8} md={12} sm={24} key={w.id} onClick={this.onWidgetSelect(w)}>
  142. <div className={widgetClassName}>
  143. <h3 className={styles.title}>{w.name}</h3>
  144. <p className={styles.content}>{w.description}</p>
  145. <i className={`${styles.pic} iconfont ${iconMapping[widgetType]}`} />
  146. {checkmark}
  147. </div>
  148. </Col>
  149. )
  150. })
  151. const wrapperCls = classnames({
  152. [className]: !!className
  153. })
  154. return (
  155. <div className={wrapperCls}>
  156. <Row gutter={20} className={`${styles.searchRow}`}>
  157. <Col span={17}>
  158. <Checkbox checked={showSelected} onChange={this.onShowTypeChange}>已选</Checkbox>
  159. </Col>
  160. <Col span={7}>
  161. <Search
  162. placeholder="可视化组件 名称"
  163. onSearch={this.onSearchWidgetItem}
  164. />
  165. </Col>
  166. </Row>
  167. <Row gutter={20}>
  168. {widgetsList}
  169. </Row>
  170. <Row>
  171. <Pagination
  172. simple={screenWidth < 768 || screenWidth === 768}
  173. className={styles.paginationPosition}
  174. showSizeChanger
  175. onShowSizeChange={this.onShowSizeChange}
  176. onChange={this.onChange}
  177. total={widgetsFiltered.length}
  178. defaultPageSize={24}
  179. pageSizeOptions={['24', '48', '72', '96']}
  180. current={currentPage}
  181. />
  182. </Row>
  183. </div>
  184. )
  185. }
  186. }
  187. export default WidgetSelector