/* * << * Davinci * == * Copyright (C) 2016 - 2017 EDP * == * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * >> */ import React from 'react' import classnames from 'classnames' import { Radio, Select, Button, Icon, message } from 'antd' const RadioGroup = Radio.Group const Option = Select.Option import { SQL_NUMBER_TYPES, SQL_DATE_TYPES } from 'app/globalConstants' const utilStyles = require('assets/less/util.less') const styles = require('../Dashboard.less') interface IDrillPathSettingProps { widgets: any[] views: any[] itemId: number | boolean selectedWidget: number[] drillpathSetting: any[] saveDrillPathSetting: (flag: any) => any cancel: () => any } interface IDrillPathSettingStates { screenWidth: number value: number pathNodes: IPathNode[] pathOrFree: string } export interface IPathNode { views: any[] widget: string enter: string out: string enterType: string outType: string nextRelation: string enterErrorMessage: string outErrorMessage: string } export class DrillPathSetting extends React.PureComponent { constructor (props) { super(props) this.state = { screenWidth: 0, value: 1, pathNodes: [], pathOrFree: 'free' } } private getViewList = (widgetId) => { const {views, widgets} = this.props const view = views.find((view) => view.id === (widgets.find((widget) => widget.id === widgetId))['viewId']) const { model } = view const modelObj = JSON.parse(model) const viewLists = [] Object.entries(modelObj).forEach(([key, m]) => { m['name'] = key viewLists.push(m) }) return viewLists } private init = () => { const {selectedWidget, drillpathSetting} = this.props const viewLists = this.getViewList(selectedWidget[0]) let newPathNodes = void 0 if (drillpathSetting && drillpathSetting.length) { newPathNodes = drillpathSetting this.setState({ pathOrFree: 'path' }) } else { newPathNodes = [{ widget: `${selectedWidget[0]}`, views: viewLists, enter: '', out: '', enterType: '', outType: '', nextRelation: '=', enterErrorMessage: '', outErrorMessage: '' }] } this.setState({ pathNodes: newPathNodes }) } public componentWillMount () { this.init() } public componentWillReceiveProps (nextProps) { window.addEventListener('resize', this.getScreenWidth, false) const {selectedWidget, drillpathSetting} = this.props const nextSelectedWidget = nextProps.selectedWidget const nextDrillpathSetting = nextProps.drillpathSetting if (selectedWidget[0] !== nextSelectedWidget [0]) { const startPathObj = this.state.pathNodes[0] startPathObj['widget'] = nextSelectedWidget[0] const newPathNodes = [...this.state.pathNodes] newPathNodes.splice(0, 1, startPathObj) this.setState({ pathNodes: newPathNodes }) } } public componentWillUnmount () { window.removeEventListener('resize', this.getScreenWidth, false) } private getScreenWidth = () => { this.setState({ screenWidth: document.documentElement.clientWidth }) } private onChange = (e) => { this.setState({ pathOrFree: e.target.value }) } private generateFilterOperatorOptions = (type) => { const operators = [ ['=', 'like', '>', '<', '>=', '<=', '!='], ['=', '>', '<', '>=', '<=', '!='] ] const stringOptions = operators[0].slice().map((o) => ( )) const numbersAndDateOptions = operators[1].slice().map((o) => ( )) if (SQL_NUMBER_TYPES.indexOf(type) >= 0 || SQL_DATE_TYPES.indexOf(type) >= 0) { return numbersAndDateOptions } else { return stringOptions } } private add = () => { const obj = { widget: '', views: [], enter: '', out: '', enterType: '', outType: '', nextRelation: '=', enterErrorMessage: '', outErrorMessage: '' } const {pathNodes} = this.state const newNodes = pathNodes.concat(obj) this.setState({ pathNodes: newNodes }) } private remove = (index: number) => () => { const pathNodes = [...this.state.pathNodes] pathNodes.splice(index, 1) this.setState({ pathNodes }) } private saveDrillPathSetting = () => { const {saveDrillPathSetting} = this.props const result = this.checkDrillPathSettingValidate() if (result && saveDrillPathSetting) { if (this.state.pathOrFree === 'free') { saveDrillPathSetting([]) } else { saveDrillPathSetting(this.state.pathNodes) } this.hideDrillPathSettingModal() } } private getNewPathNodes = (index, field, value) => { const startPathObj = this.state.pathNodes[index] startPathObj[field] = value const newPathNodes = [...this.state.pathNodes] newPathNodes.splice(index, 1, startPathObj) return newPathNodes } private checkDrillPathSettingValidate = () => { const { pathNodes, pathOrFree } = this.state let validate = true if (pathOrFree === 'path' && pathNodes.length === 1) { validate = false message.error('至少设置两个路径') } for (let index = 0, l = pathNodes.length; index < l; index++) { const node = pathNodes[index] if (index !== 0) { if (node.enter === '') { const newPathNodes = this.getNewPathNodes(index, 'enterErrorMessage', '入参为必填项') this.setState({ pathNodes: newPathNodes }) validate = false return validate } else { const newPathNodes = this.getNewPathNodes(index, 'enterErrorMessage', '') this.setState({ pathNodes: newPathNodes }) } } if (index !== (this.state.pathNodes.length - 1)) { if (node.out === '') { const newPathNodes = this.getNewPathNodes(index, 'outErrorMessage', '出参为必填项') this.setState({ pathNodes: newPathNodes }) validate = false return validate } else { const newPathNodes = this.getNewPathNodes(index, 'outErrorMessage', '') this.setState({ pathNodes: newPathNodes }) } } } return validate } private hideDrillPathSettingModal = () => { const {cancel} = this.props if (cancel) { cancel() } } private changeWidget = (index) => (value) => { const startPathObj = this.state.pathNodes[index] const viewLists = this.getViewList(Number(value)) startPathObj['widget'] = value startPathObj['views'] = viewLists const newPathNodes = [...this.state.pathNodes] newPathNodes.splice(index, 1, startPathObj) this.setState({ pathNodes: newPathNodes }) const result = this.checkDrillPathSettingValidate() } private changeParams = (index, category, views?: any[]) => (value) => { const startPathObj = this.state.pathNodes[index] startPathObj[category] = value if (views && views.length) { startPathObj[`${category}Type`] = (views.find((view) => view.name === value))['sqlType'] } const newPathNodes = [...this.state.pathNodes] newPathNodes.splice(index, 1, startPathObj) this.setState({ pathNodes: newPathNodes }) const result = this.checkDrillPathSettingValidate() } public render () { const { itemId, widgets, views, selectedWidget, drillpathSetting } = this.props const { screenWidth, pathNodes } = this.state const formItemStyle = { marginBottom: '8px' } const drillSettingButtons = [( ), ( )] const widgetOptions = widgets.length && widgets.map((widget) => ( )) const pathDrill = pathNodes.length && pathNodes.map((node, index) => { const paramOptions = node && node.views && node.views.map((view) => { return ( )}) const relationOptions = this.generateFilterOperatorOptions(node.outType) return (

{this.state.pathNodes.length > 1 ? : null}

{index + 1}

{node.enterErrorMessage && node.enterErrorMessage.length ? node.enterErrorMessage : ''}
{node.outErrorMessage && node.outErrorMessage.length ? node.outErrorMessage : ''}
)}) const pathStyle = classnames({ [utilStyles.hide]: this.state.pathOrFree !== 'path' }) return (
钻取模式: 自由钻取 路径钻取
{pathDrill}
{/*
{drillSettingButtons}
*/}
{drillSettingButtons}
) } } export default DrillPathSetting