123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- import React from 'react'
- import classnames from 'classnames'
- import produce from 'immer'
- import set from 'lodash/set'
- import { uuid } from 'utils/util'
- import { fontWeightOptions, fontStyleOptions, fontFamilyOptions, fontSizeOptions } from '../constants'
- import { defaultConditionStyle, AvailableTableConditionStyleTypes } from './constants'
- import { getColumnIconByType } from './util'
- import { ITableColumnConfig, ITableConditionStyle } from './types'
- import ColorPicker from 'components/ColorPicker'
- import ConditionStyleConfigModal from './ConditionStyleConfigModal'
- import { Row, Col, Tooltip, Form, Select, InputNumber, Button, Radio, Checkbox, Table, Modal } from 'antd'
- const RadioGroup = Radio.Group
- const RadioButton = Radio.Button
- const FormItem = Form.Item
- import styles from './styles.less'
- import stylesConfig from '../styles.less'
- interface IColumnStyleConfigProps {
- visible: boolean
- config: ITableColumnConfig[]
- onCancel: () => void
- onSave: (config: ITableColumnConfig[]) => void
- }
- interface IColumnStyleConfigStates {
- localConfig: ITableColumnConfig[]
- selectedColumnName: string
- conditionStyleConfigModalVisible: boolean
- currentConditionStyle: ITableConditionStyle
- }
- export class ColumnStyleConfig extends React.PureComponent<IColumnStyleConfigProps, IColumnStyleConfigStates> {
- public constructor (props: IColumnStyleConfigProps) {
- super(props)
- const localConfig = props.config
- this.state = {
- localConfig,
- selectedColumnName: localConfig.length > 0 ? localConfig[0].columnName : '',
- conditionStyleConfigModalVisible: false,
- currentConditionStyle: null
- }
- }
- public componentWillReceiveProps (nextProps: IColumnStyleConfigProps) {
- if (nextProps.config === this.props.config) { return }
- const localConfig = nextProps.config
- this.setState({
- localConfig,
- selectedColumnName: localConfig.length > 0 ? localConfig[0].columnName : '',
- conditionStyleConfigModalVisible: false,
- currentConditionStyle: null
- })
- }
- private renderColumn (item: ITableColumnConfig) {
- const { selectedColumnName } = this.state
- const { columnName, alias, visualType } = item
- const displayName = alias || columnName
- const itemCls = classnames({
- [styles.selected]: selectedColumnName === columnName
- })
- return (
- <li className={itemCls} key={columnName} onClick={this.selectColumn(columnName)}>
- <i className={`iconfont ${getColumnIconByType(visualType)}`} />
- <Tooltip title={displayName} mouseEnterDelay={0.8}>
- <label>{displayName}</label>
- </Tooltip>
- </li>
- )
- }
- private selectColumn = (columnName: string) => () => {
- this.setState({
- selectedColumnName: columnName
- })
- }
- private propChange = (
- propPath: Exclude<keyof(ITableColumnConfig), 'style'> | ['style', keyof ITableColumnConfig['style']]
- ) => (e) => {
- const value = e.target ? (e.target.value || e.target.checked) : e
- const { localConfig, selectedColumnName } = this.state
- const nextLocalConfig = produce(localConfig, (draft) => {
- const selectedColumn = draft.find(({ columnName }) => columnName === selectedColumnName)
- set(selectedColumn, propPath, value)
- return draft
- })
- this.setState({
- localConfig: nextLocalConfig
- })
- }
- private cancel = () => {
- this.props.onCancel()
- }
- private save = () => {
- this.props.onSave(this.state.localConfig)
- }
- private columns = [{
- title: '',
- dataIndex: 'idx',
- width: 30,
- render: (_, __, index) => (index + 1)
- }, {
- title: '样式类型',
- dataIndex: 'type',
- width: 50,
- render: (type) => AvailableTableConditionStyleTypes[type]
- }, {
- title: '操作',
- dataIndex: 'operation',
- width: 60,
- render: (_, record) => (
- <div className={styles.btns}>
- <Button onClick={this.editConditionStyle(record)} icon="edit" shape="circle" size="small" />
- <Button onClick={this.deleteConditionStyle(record.key)} icon="delete" shape="circle" size="small" />
- </div>
- )
- }]
- private addConditionStyle = () => {
- this.setState({
- conditionStyleConfigModalVisible: true,
- currentConditionStyle: {
- ...defaultConditionStyle
- }
- })
- }
- private editConditionStyle = (record) => () => {
- this.setState({
- currentConditionStyle: record,
- conditionStyleConfigModalVisible: true
- })
- }
- private deleteConditionStyle = (deletedKey: string) => () => {
- const { localConfig, selectedColumnName } = this.state
- const nextLocalConfig = produce(localConfig, (draft) => {
- const selectedColumn = draft.find(({ columnName }) => columnName === selectedColumnName)
- const idx = selectedColumn.conditionStyles.findIndex(({ key }) => key === deletedKey)
- selectedColumn.conditionStyles.splice(idx, 1)
- })
- this.setState({ localConfig: nextLocalConfig })
- }
- private closeConditionStyleConfig = () => {
- this.setState({
- conditionStyleConfigModalVisible: false,
- currentConditionStyle: null
- })
- }
- private saveConditionStyleConfig = (conditionStyle: ITableConditionStyle) => {
- const { localConfig, selectedColumnName } = this.state
- const nextLocalConfig = produce(localConfig, (draft) => {
- const selectedColumn = draft.find(({ columnName }) => columnName === selectedColumnName)
- if (conditionStyle.key) {
- const idx = selectedColumn.conditionStyles.findIndex(({ key }) => key === conditionStyle.key)
- selectedColumn.conditionStyles.splice(idx, 1, conditionStyle)
- } else {
- selectedColumn.conditionStyles.push({ ...conditionStyle, key: uuid(5) })
- }
- })
- this.setState({
- localConfig: nextLocalConfig,
- conditionStyleConfigModalVisible: false,
- currentConditionStyle: null
- })
- }
- private modalFooter = [(
- <Button
- key="cancel"
- size="large"
- onClick={this.cancel}
- >
- 取 消
- </Button>
- ), (
- <Button
- key="submit"
- size="large"
- type="primary"
- onClick={this.save}
- >
- 保 存
- </Button>
- )]
- public render () {
- const { visible } = this.props
- const {
- localConfig, selectedColumnName,
- conditionStyleConfigModalVisible, currentConditionStyle } = this.state
- if (localConfig.length <= 0) {
- return (<div />)
- }
- const { style, visualType, sort, conditionStyles } = localConfig.find((c) => c.columnName === selectedColumnName)
- const { fontSize, fontFamily, fontWeight, fontColor, fontStyle, backgroundColor, justifyContent, inflexible, width } = style
- return (
- <Modal
- title="数据列设置"
- wrapClassName="ant-modal-large"
- maskClosable={false}
- footer={this.modalFooter}
- visible={visible}
- onCancel={this.cancel}
- onOk={this.save}
- >
- <div className={styles.columnStyleConfig}>
- <div className={styles.left}>
- <div className={styles.title}>
- <h2>字段列表</h2>
- </div>
- <div className={styles.list}>
- <ul>
- {localConfig.map((item) => this.renderColumn(item))}
- </ul>
- </div>
- </div>
- <div className={styles.right}>
- <div className={styles.title}><h2>排序与过滤</h2></div>
- <div className={stylesConfig.rows}>
- <Row gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
- <Col span={12}>
- <Checkbox checked={sort} onChange={this.propChange('sort')}>开启列排序</Checkbox>
- </Col>
- </Row>
- </div>
- <div className={styles.title}><h2>基础样式</h2></div>
- <div className={stylesConfig.rows}>
- <Row gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
- <Col span={3}>
- <FormItem label="背景色">
- <div className={styles.colorPickerWrapper}>
- <ColorPicker
- className={stylesConfig.color}
- value={backgroundColor}
- onChange={this.propChange(['style', 'backgroundColor'])}
- />
- </div>
- </FormItem>
- </Col>
- <Col span={9}>
- <FormItem label="对齐">
- <RadioGroup size="small" value={justifyContent} onChange={this.propChange(['style', 'justifyContent'])}>
- <RadioButton value="flex-start">左对齐</RadioButton>
- <RadioButton value="center">居中</RadioButton>
- <RadioButton value="flex-end">右对齐</RadioButton>
- </RadioGroup>
- </FormItem>
- </Col>
- <Col span={5}>
- <FormItem label="列宽">
- <Checkbox
- checked={inflexible}
- onChange={this.propChange(['style', 'inflexible'])}
- >
- 固定列宽
- </Checkbox>
- </FormItem>
- </Col>
- <Col span={5}>
- <FormItem label=" " colon={false}>
- <InputNumber
- size="small"
- className={stylesConfig.colControl}
- placeholder="设置列宽"
- value={width}
- disabled={!inflexible}
- onChange={this.propChange(['style', 'width'])}
- />
- </FormItem>
- </Col>
- </Row>
- <Row gutter={8} type="flex" align="middle" className={stylesConfig.rowBlock}>
- <Col span={4}>
- <FormItem label="字体与样式">
- <Select
- size="small"
- className={stylesConfig.colControl}
- placeholder="字体"
- value={fontFamily}
- onChange={this.propChange(['style', 'fontFamily'])}
- >
- {fontFamilyOptions}
- </Select>
- </FormItem>
- </Col>
- <Col span={4}>
- <FormItem label=" " colon={false}>
- <Select
- size="small"
- className={stylesConfig.colControl}
- placeholder="文字大小"
- value={fontSize}
- onChange={this.propChange(['style', 'fontSize'])}
- >
- {fontSizeOptions}
- </Select>
- </FormItem>
- </Col>
- <Col span={4}>
- <FormItem label=" " colon={false}>
- <Select
- size="small"
- className={stylesConfig.colControl}
- value={fontStyle}
- onChange={this.propChange(['style', 'fontStyle'])}
- >
- {fontStyleOptions}
- </Select>
- </FormItem>
- </Col>
- <Col span={5}>
- <FormItem label=" " colon={false}>
- <Select
- size="small"
- className={stylesConfig.colControl}
- value={fontWeight}
- onChange={this.propChange(['style', 'fontWeight'])}
- >
- {fontWeightOptions}
- </Select>
- </FormItem>
- </Col>
- <Col span={3}>
- <FormItem label=" " colon={false}>
- <ColorPicker
- className={stylesConfig.color}
- value={fontColor}
- onChange={this.propChange(['style', 'fontColor'])}
- />
- </FormItem>
- </Col>
- </Row>
- </div>
- <div className={styles.title}>
- <h2>条件样式</h2>
- <Button type="primary" onClick={this.addConditionStyle} shape="circle" icon="plus" size="small" />
- </div>
- <div className={styles.table}>
- <Table
- bordered={true}
- pagination={false}
- columns={this.columns}
- dataSource={conditionStyles}
- />
- </div>
- </div>
- </div>
- <ConditionStyleConfigModal
- visible={conditionStyleConfigModalVisible}
- visualType={visualType}
- style={currentConditionStyle}
- onCancel={this.closeConditionStyleConfig}
- onSave={this.saveConditionStyleConfig}
- />
- </Modal>
- )
- }
- }
- export default ColumnStyleConfig
|