DropboxItem.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. import React from 'react'
  2. import classnames from 'classnames'
  3. import { AggregatorType, IDataParamSource, IDataParamSourceInBox } from '../Dropbox'
  4. import PivotChartSelector from '../PivotChartSelector'
  5. import { getFieldAlias } from '../../Config/Field'
  6. import { FieldSortTypes } from '../../Config/Sort'
  7. import { getAggregatorLocale, decodeMetricName } from '../../util'
  8. import { IChartInfo } from '../../Widget'
  9. import { getAvailableSettings, getSettingsDropdownList, getSettingKeyByDropItem, MapSettingTypes, MapItemTypes, MapItemValueTypes } from './settings'
  10. import { Icon, Menu, Dropdown, Tooltip } from 'antd'
  11. const { Item: MenuItem, SubMenu, Divider: MenuDivider } = Menu
  12. const styles = require('../Workbench.less')
  13. interface IDropboxItemProps {
  14. container: string
  15. item: IDataParamSourceInBox
  16. dimetionsCount: number
  17. metricsCount: number
  18. onDragStart: (item: IDataParamSource, e: React.DragEvent<HTMLLIElement | HTMLParagraphElement>) => void
  19. onDragEnd: () => void
  20. onSort: (item: IDataParamSource, sort: FieldSortTypes) => void
  21. onChangeAgg: (item: IDataParamSource, agg: AggregatorType) => void
  22. onChangeFieldConfig: (item: IDataParamSource) => void
  23. onChangeFormatConfig: (item: IDataParamSource) => void
  24. onChangeColorConfig: (item: IDataParamSource) => void
  25. onChangeFilterConfig: (item: IDataParamSource) => void
  26. onChangeChart: (item: IDataParamSource) => (chart: IChartInfo) => void
  27. onRemove: (e) => void
  28. }
  29. interface IDropboxItemStates {
  30. dragging: boolean
  31. }
  32. export class DropboxItem extends React.PureComponent<IDropboxItemProps, IDropboxItemStates> {
  33. constructor (props) {
  34. super(props)
  35. this.state = {
  36. dragging: false
  37. }
  38. }
  39. private dragStart = (e) => {
  40. const { item, onDragStart } = this.props
  41. // hack firefox trigger dragEnd
  42. e.persist()
  43. if (item.type !== 'add') {
  44. this.setState({
  45. dragging: true
  46. }, () => {
  47. onDragStart(item as IDataParamSource, e)
  48. })
  49. setTimeout(() => {
  50. e.target.classList.add(styles.dragged)
  51. })
  52. }
  53. }
  54. private dragEnd = () => {
  55. this.props.onDragEnd()
  56. this.setState({
  57. dragging: false
  58. })
  59. }
  60. private dropdownMenuClick = ({ key }: { key: string }) => {
  61. const {
  62. item,
  63. onChangeAgg,
  64. onChangeFieldConfig,
  65. onChangeFormatConfig,
  66. onSort,
  67. onChangeColorConfig,
  68. onChangeFilterConfig } = this.props
  69. const settingKey = getSettingKeyByDropItem(key)
  70. switch (settingKey) {
  71. case 'aggregator':
  72. onChangeAgg(item as IDataParamSource, key as AggregatorType)
  73. break
  74. case 'color':
  75. onChangeColorConfig(item as IDataParamSource)
  76. break
  77. case 'field':
  78. onChangeFieldConfig(item as IDataParamSource)
  79. break
  80. case 'filters':
  81. onChangeFilterConfig(item as IDataParamSource)
  82. break
  83. case 'format':
  84. onChangeFormatConfig(item as IDataParamSource)
  85. break
  86. case 'sort':
  87. onSort(item as IDataParamSource, key as FieldSortTypes)
  88. break
  89. }
  90. }
  91. public render () {
  92. const { container, item, dimetionsCount, metricsCount, onChangeChart, onRemove } = this.props
  93. const { name: originalName, type, sort, agg, field } = item
  94. const { dragging } = this.state
  95. const name = type === 'value' ? decodeMetricName(originalName) : originalName
  96. let pivotChartSelector
  97. if (container === 'metrics' && item.type !== 'add') {
  98. pivotChartSelector = (
  99. <PivotChartSelector
  100. chart={item.chart}
  101. dimetionsCount={dimetionsCount}
  102. metricsCount={metricsCount}
  103. onChangeChart={onChangeChart(item as IDataParamSource)}
  104. />
  105. )
  106. }
  107. const itemClass = classnames({
  108. [styles.dropItemContent]: true,
  109. [styles.category]: type === 'category',
  110. [styles.value]: type === 'value',
  111. [styles.add]: type === 'add',
  112. [styles.dragging]: dragging
  113. })
  114. const sortClass = classnames({
  115. 'iconfont': true,
  116. [styles.sort]: true,
  117. 'icon-sortascending': sort && sort.sortType === FieldSortTypes.Asc,
  118. 'icon-sortdescending': sort && sort.sortType === FieldSortTypes.Desc,
  119. 'icon-zidingyipaixu': sort && sort.sortType === FieldSortTypes.Custom
  120. })
  121. const desc = field ? field.desc : ''
  122. const aliasText = getFieldAlias(field, {})
  123. const content = (
  124. <p>
  125. <Icon type="down" />
  126. {agg ? ` [${getAggregatorLocale(agg)}] ${name} ` : ` ${name} `}
  127. {aliasText && (
  128. <Tooltip title={desc} placement="right">
  129. {`[${aliasText}]`}
  130. </Tooltip>
  131. )}
  132. {sort && <i className={sortClass} />}
  133. </p>
  134. )
  135. let contentWithDropdownList
  136. if (type === 'add') {
  137. contentWithDropdownList = content
  138. } else {
  139. const availableSettings = getAvailableSettings(MapSettingTypes[container], MapItemTypes[item.type], MapItemValueTypes[item.visualType])
  140. const dropdownList = getSettingsDropdownList(availableSettings)
  141. let menuClass = ''
  142. if (type === 'value') {
  143. menuClass = styles.valueDropDown
  144. }
  145. contentWithDropdownList = (
  146. <Dropdown
  147. overlay={(
  148. <Menu className={menuClass} onClick={this.dropdownMenuClick}>
  149. {dropdownList}
  150. </Menu>
  151. )}
  152. trigger={['click']}
  153. >
  154. {content}
  155. </Dropdown>
  156. )
  157. }
  158. return (
  159. <div className={styles.dropItem}>
  160. <div
  161. className={itemClass}
  162. onDragStart={this.dragStart}
  163. onDragEnd={this.dragEnd}
  164. draggable
  165. >
  166. {pivotChartSelector}
  167. {contentWithDropdownList}
  168. <Icon
  169. type="close-square-o"
  170. className={styles.remove}
  171. onClick={onRemove}
  172. />
  173. </div>
  174. </div>
  175. )
  176. }
  177. }
  178. export default DropboxItem