import React from 'react' import classnames from 'classnames' import moment, { Moment } from 'moment' import OperatorTypes from 'utils/operatorTypes' import { Row, Col, Input, InputNumber, DatePicker, Button, Tag, Switch } from 'antd' import { DEFAULT_DATETIME_FORMAT } from 'app/globalConstants' import Styles from './ConditionValuesControl.less' export type ConditionValueTypes = string | number | boolean interface IConditionValuesControlProps { className?: string size: 'small' | 'default' visualType: string operatorType: OperatorTypes conditionValues: ConditionValueTypes[] onChange: (values: ConditionValueTypes[]) => void } interface IConditionValuesControlStates { localValues: ConditionValueTypes[] tagInputting: boolean tagInputValue: ConditionValueTypes } export class ConditionValuesControl extends React.PureComponent { public static defaultProps: Partial = { size: 'default' } private controlStyle: React.CSSProperties = { width: '100%' } public constructor (props: IConditionValuesControlProps) { super(props) this.state = { localValues: [], tagInputting: false, tagInputValue: '' } } public componentDidMount () { const { operatorType, visualType, conditionValues } = this.props this.initLocalValues(operatorType, visualType, conditionValues) } public componentWillReceiveProps (nextProps: IConditionValuesControlProps) { const { visualType, operatorType, conditionValues } = nextProps this.initLocalValues(operatorType, visualType, conditionValues) } private initLocalValues ( operatorType: OperatorTypes, visualType: string, conditionValues: ConditionValueTypes[] ) { const values = [] const initValue = this.getInitValueByVisualType(visualType) let valuesCount = 0 switch (operatorType) { case OperatorTypes.Contain: case OperatorTypes.Equal: case OperatorTypes.GreaterThan: case OperatorTypes.GreaterThanOrEqual: case OperatorTypes.LessThan: case OperatorTypes.LessThanOrEqual: case OperatorTypes.NotEqual: valuesCount = 1 break case OperatorTypes.Between: valuesCount = 2 break case OperatorTypes.In: valuesCount = conditionValues.length break } for (let idx = 0; idx < valuesCount; idx++) { if (conditionValues[idx] && typeof conditionValues[idx] === typeof initValue) { values.push(conditionValues[idx]) } else { values.push(initValue) } } this.setState({ localValues: values }) } private getInitValueByVisualType (visualType: string): ConditionValueTypes { switch (visualType) { case 'string': case 'geoCountry': case 'geoProvince': case 'geoCity': return '' case 'number': return 0 case 'date': return moment().format('YYYY-MM-DD') case 'boolean': return false default: return null } } private getControlValueByVisualType (visualType: string, args: any[]) { let value: ConditionValueTypes switch (visualType) { case 'string': case 'geoCountry': case 'geoProvince': case 'geoCity': value = (args[0] as React.ChangeEvent).target.value break case 'number': case 'boolean': value = args[0] break case 'date': value = args[1] break } return value } private localValuesChange = (idx: number) => (...args: any[]) => { const { onChange, visualType } = this.props const value = this.getControlValueByVisualType(visualType, args) const { localValues } = this.state const values = [...localValues] values.splice(idx, 1, value) onChange(values) } private renderControl = (idx: number) => { const { visualType, size } = this.props const { localValues } = this.state let control: React.ReactNode switch (visualType) { case 'string': case 'geoCountry': case 'geoProvince': case 'geoCity': const stringValue = localValues[idx] as string control = ( ) break case 'number': const numberValue = localValues[idx] as number control = ( ) break case 'date': const dateValue = moment(localValues[idx] as string) control = ( ) break case 'boolean': const booleanValue = localValues[idx] as boolean control = ( ) } return control } private renderRow = () => { const { operatorType } = this.props let controls: React.ReactNode switch (operatorType) { case OperatorTypes.Contain: case OperatorTypes.Equal: case OperatorTypes.GreaterThan: case OperatorTypes.GreaterThanOrEqual: case OperatorTypes.LessThan: case OperatorTypes.LessThanOrEqual: case OperatorTypes.NotEqual: controls = this.renderControl(0) break case OperatorTypes.Between: controls = ( {this.renderControl(0)} - {this.renderControl(1)} ) break case OperatorTypes.In: controls = this.renderTags() break } return controls } private renderTags = () => { const { visualType, size } = this.props const { localValues, tagInputting, tagInputValue } = this.state const tagList = localValues.map((val) => ( {val} )) const tagInputControl = [] if (tagInputting) { switch (visualType) { case 'string': case 'geoCountry': case 'geoProvince': case 'geoCity': tagInputControl.push( ) break case 'number': tagInputControl.push( ) break case 'date': const dateValue = moment((tagInputValue || moment().format('YYYY-MM-DD')) as string) tagInputControl.push( ) break } tagInputControl.push( ) } else { tagInputControl.push( ) } const rowCls = classnames({ [Styles.rowBlock]: true, [Styles.tagList]: true }) return ( {tagList}{tagInputControl} ) } private showTagInput = () => { this.setState({ tagInputting: true }) } private addTag = () => { const { tagInputValue, localValues } = this.state if (tagInputValue) { const { onChange, visualType, operatorType } = this.props onChange([...localValues.filter((val) => val !== tagInputValue), tagInputValue]) this.setState({ tagInputting: false, tagInputValue: this.getInitValueByVisualType(visualType) }) } } private removeTag = (tag) => () => { const { onChange } = this.props const { localValues } = this.state onChange(localValues.filter((val) => val !== tag)) } private tagInputValueChange = (...args: any[]) => { const { visualType } = this.props const tagInputValue = this.getControlValueByVisualType(visualType, args) this.setState({ tagInputValue }) } public render () { const { className } = this.props return (
{this.renderRow()}
) } } export default ConditionValuesControl