From 951b8691c93fe995c9e7f1f7264706e61ea39b28 Mon Sep 17 00:00:00 2001 From: manzhenhua Date: Thu, 12 Mar 2020 14:15:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/DataView/filterModal/index.js | 22 +++ components/DataView/filterModal/readme.md | 0 components/DataView/filterModal/styles.less | 15 ++ .../DataView/popoverFilter/hide/index.js | 70 +++++++ .../DataView/popoverFilter/hide/index.less | 86 +++++++++ components/DataView/popoverFilter/index.js | 178 ++++++++++++++++++ components/DataView/popoverFilter/styles.less | 83 ++++++++ components/IconFont/IconFont.js | 7 + components/IconFont/index.js | 15 ++ components/IconFont/styles.less | 5 + components/SearchView/index.js | 154 +++++++++------ components/SearchView/index.less | 15 +- 12 files changed, 591 insertions(+), 59 deletions(-) create mode 100644 components/DataView/filterModal/index.js create mode 100644 components/DataView/filterModal/readme.md create mode 100644 components/DataView/filterModal/styles.less create mode 100644 components/DataView/popoverFilter/hide/index.js create mode 100644 components/DataView/popoverFilter/hide/index.less create mode 100644 components/DataView/popoverFilter/index.js create mode 100644 components/DataView/popoverFilter/styles.less create mode 100755 components/IconFont/IconFont.js create mode 100644 components/IconFont/index.js create mode 100644 components/IconFont/styles.less diff --git a/components/DataView/filterModal/index.js b/components/DataView/filterModal/index.js new file mode 100644 index 0000000..4bd71e6 --- /dev/null +++ b/components/DataView/filterModal/index.js @@ -0,0 +1,22 @@ +import React from 'react'; +import Modal from '@/ant_components/BIModal'; +import styles from './styles.less'; + + +class FilterModal extends React.Component { + render() { + return ( + +
+ +
+
+ ) + } +} +export default FilterModal; \ No newline at end of file diff --git a/components/DataView/filterModal/readme.md b/components/DataView/filterModal/readme.md new file mode 100644 index 0000000..e69de29 diff --git a/components/DataView/filterModal/styles.less b/components/DataView/filterModal/styles.less new file mode 100644 index 0000000..1ee0e14 --- /dev/null +++ b/components/DataView/filterModal/styles.less @@ -0,0 +1,15 @@ +.modalCla{ + :global .ant-modal-body{ + padding: 0; + } + :global .ant-modal-footer{ + display: flex; + justify-content: center; + background:rgba(255,255,255,1); + } + .wrap{ + display: flex; + flex-flow: row; + min-height: 700px; + } +} \ No newline at end of file diff --git a/components/DataView/popoverFilter/hide/index.js b/components/DataView/popoverFilter/hide/index.js new file mode 100644 index 0000000..731e0bd --- /dev/null +++ b/components/DataView/popoverFilter/hide/index.js @@ -0,0 +1,70 @@ +import React, { Component } from 'react'; +import { Switch, Popover } from 'antd'; +import Icon from '@/submodule/components/IconFont'; +import _ from 'lodash'; +import s from './index.less'; +import hideIcon from '@/assets/airTable/hide.png'; +/** + * 操作栏显隐控制 + * 参数 + * @configs 操作栏配置 + * @columns 表头列表配置 + * @onChange 显隐变化回调 + */ +export default class Hide extends Component { + constructor(props) { + super(props); + this.state = { + visible: false, + columnConfig: props.columnConfig, + }; + } + + + + toggleOption = () => { + const { visible } = this.state; + this.setState({ + visible: !visible, + }); + }; + + renderContent = () => { + const { columnConfig = [] } = this.state; + const { conditions } = this.props; + return ( +
+
+ {conditions.map((item, i) => { + return ( +
+ + {item.label} +
+ ); + })} +
+
+ ); + }; + + render() { + return ( + + 添加筛选条件 + + ); + } +} diff --git a/components/DataView/popoverFilter/hide/index.less b/components/DataView/popoverFilter/hide/index.less new file mode 100644 index 0000000..a73fb55 --- /dev/null +++ b/components/DataView/popoverFilter/hide/index.less @@ -0,0 +1,86 @@ +@import "~@/theme/common"; + +.popover { + :global(.ant-popover-inner-content) { + padding: 0; + } + + :global(.ant-popover-title) { + padding: 14px 16px; + } +} + +.operateContainer { + cursor: pointer; + text-align: center; + padding: 5px 8px; + border-radius: 2px; + + &:hover { + background: #F6F6F6; + } + + .operateIcon { + width: 14px; + height: 12px; + margin-right: 3px; + } + + .operateName { + font-size: 14px; + font-weight: 400; + color: @textPrimaryColor; + } + + &:hover { + background: #F6F6F6; + } + + &.selected { + background: @primaryColor; + } +} + +.optionsModal { + min-width: 174px; + padding-top: 10px; + + .optionList { + max-height: 300px; + overflow: auto; + + .optionItem { + padding: 0 10px; + margin-bottom: 5px; + cursor: pointer; + + .optionName { + margin-left: 10px; + } + } + } + + .btns { + width: 100%; + height: 44px; + background: #F6F6F6; + display: flex; + align-items: center; + justify-content: space-around; + + .btn { + //width: 50%; + font-size: 12px; + color: @textGeneralColor; + cursor: pointer; + + &:last-child { + color: @primaryColor; + } + } + } +} +.addBtn{ + cursor: pointer; + color: @primaryColor; +} diff --git a/components/DataView/popoverFilter/index.js b/components/DataView/popoverFilter/index.js new file mode 100644 index 0000000..860f1e2 --- /dev/null +++ b/components/DataView/popoverFilter/index.js @@ -0,0 +1,178 @@ +import React, { Component } from 'react'; +import { fromJS, Map, List, is } from 'immutable'; +import { Popover, message } from 'antd'; +import Button from '@/ant_components/BIButton'; +import classnamse from 'classnames'; +import SearchView from '@/submodule/components/SearchView'; +import BISelect from '@/ant_components/BISelect'; +import filterIcon from '@/assets/airTable/filter.png'; +import closeIcon from '@/assets/airTable/close.png'; +import SettingPanel from './hide' +import styles from './styles.less'; + +const TransType = ['2', '3', '4', '13', '14']; +/** + * 操作栏过滤条件控制 + * 参数 + * @filterValues 已有的过滤条件 + * @filterColumnConfig 可以过滤的配置项 + * @onChange 变化回调 + * @hideSettingPanel 设置过滤条件 + * @conditions 全量条件数据 + * @openSettingPanel 打开设置变量看板 + * @closeSettingPanel 关闭设置变量看板 + * @selectedConditions 已选择条件数据 + * + */ +export default class Filter extends Component { + constructor(props) { + super(props); + this.state = { + visible: false, + filterConfig: props.filterConfig || [{}], + }; + } + + componentDidMount() { + const { filterConfig = [] } = this.props; + this.setState({ + filterConfig: filterConfig.length > 0 ? filterConfig : [{}], + }); + } + + componentWillReceiveProps(nextProps) { + const { filterConfig } = this.props; + const x1 = fromJS(filterConfig); + const x2 = fromJS(nextProps.filterConfig); + if (!is(x1, x2)) { + this.setState({ + filterConfig: nextProps.filterConfig.length > 0 ? nextProps.filterConfig : [{}], + }); + } + } + + toggleOption = () => { + const { visible } = this.state; + this.setState({ + visible: !visible, + }); + }; + + // 重置 + resetFilterItem = () => { + this.setState({ + filterConfig: [{}], + }); + this.onChange([]); + }; + // 改变筛选条件 + changeFilterKey = (index, value) => { + const { filterConfig } = this.state; + const { filterColumnConfig } = this.props; + const filter = filterColumnConfig.find((item) => { + return item.key === value; + }); + const data = { + colName: value, + colChsName: filter.title, + operationCode: filter.operator && filter.operator[0] && filter.operator[0].id, + colValues: undefined, + }; + const temp = List(filterConfig) + .splice(index, 1, data) + .toJS(); + this.setState({ + filterConfig: temp, + }); + }; + + // 回调表格更改操作栏方法 + onChange = (props, changedValues, allValues) => { + // const { onChange, filterConfig } = this.props; + // const x1 = fromJS(changedConfig); + // const x2 = fromJS(filterConfig); + // if (!is(x1, x2)) { + // if (typeof onChange === 'function') { + // onChange({ type: 'filterConfig', config: changedConfig }); + // } + // } + }; + // 渲染搜索栏 + _renderSearchForm = () => { + const { selectedConditions = [] } = this.props; + const { searchForm = {} } = this.state; + if (selectedConditions === null || selectedConditions.length <= 0) return null; + return ( + + ); + }; + renderContent = () => { + const { hideSettingPanel } = this.props; + return ( +
+
+ {this._renderSearchForm()} +
+
+ +
+ {hideSettingPanel ? null : } +
+
+ + +
+
+
+ ); + }; + renderOpenBtn = () => { + const { filterValues = [] } = this.props; + if (this.props.renderOpenBtn && typeof this.props.renderOpenBtn === 'function') { + return this.props.renderOpenBtn(); + } + // const len = filterValues.filter((item) => { + // return item.value > 0; + // }).length; + const len = 10 + let background = len > 0 ? 'rgba(247,181,0,0.1)' : ''; + return ( +
+ + {len > 0 ? `${len}条筛选` : '筛选'} +
+ ) + } + + render() { + return ( + + {this.renderOpenBtn()} + + ); + } +} \ No newline at end of file diff --git a/components/DataView/popoverFilter/styles.less b/components/DataView/popoverFilter/styles.less new file mode 100644 index 0000000..67cf908 --- /dev/null +++ b/components/DataView/popoverFilter/styles.less @@ -0,0 +1,83 @@ +@import "~@/theme/common"; + +.popover { + :global(.ant-popover-inner-content) { + padding: 0; + } + + :global(.ant-popover-title) { + padding: 14px 16px; + } +} + +.operateContainer { + cursor: pointer; + text-align: center; + padding: 5px 8px; + border-radius: 2px; + + &:hover { + background: #F6F6F6; + } + + .operateIcon { + width: 14px; + height: 12px; + margin-right: 3px; + } + + .operateName { + font-size: 14px; + font-weight: 400; + color: @textPrimaryColor; + } + + &:hover { + background: #F6F6F6; + } + + &.selected { + background: @primaryColor; + } +} + +.optionsModal { + width: 520px; + padding-top: 10px; +.content{ + min-height: 200px; + padding-right: 16px; +} + .optionList { + max-height: 300px; + overflow: auto; + + .optionItem { + padding: 0 10px; + margin-bottom: 5px; + cursor: pointer; + + .optionName { + margin-left: 10px; + } + } + } + + .btns { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 16px; + border-top: 1px solid #ECECECFF ; + .btn { + width: 80px; + height: 32px; + font-size: 12px; + cursor: pointer; + &:last-child { + margin-left: 16px; + } + } + } +} diff --git a/components/IconFont/IconFont.js b/components/IconFont/IconFont.js new file mode 100755 index 0000000..5701a7b --- /dev/null +++ b/components/IconFont/IconFont.js @@ -0,0 +1,7 @@ +import { Icon } from 'antd'; + +const IconFont = Icon.createFromIconfontCN({ + scriptUrl: '//at.alicdn.com/t/font_1509781_pkjtz0jd3g.js', +}); + +export default IconFont; diff --git a/components/IconFont/index.js b/components/IconFont/index.js new file mode 100644 index 0000000..b675246 --- /dev/null +++ b/components/IconFont/index.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { Icon } from 'antd'; +import IconFont from './IconFont'; +import styles from './styles.less'; + +const CustomIcon = props => { + const { type, iconFontType } = props; + const isHttp = /^((https|http)?:\/\/)[^\s]+/.test(type); + if (iconFontType) { + return + } + return isHttp ? icon : + +}; +export default CustomIcon \ No newline at end of file diff --git a/components/IconFont/styles.less b/components/IconFont/styles.less new file mode 100644 index 0000000..0d10940 --- /dev/null +++ b/components/IconFont/styles.less @@ -0,0 +1,5 @@ +.iconCls{ + // width: 20px; + height: 20px; + line-height: 20px; +} diff --git a/components/SearchView/index.js b/components/SearchView/index.js index 93fccf4..0784b79 100644 --- a/components/SearchView/index.js +++ b/components/SearchView/index.js @@ -1,7 +1,8 @@ // 库/框架 import React from 'react'; +import classnames from 'classnames'; // 第三方组件 -import { Form, TreeSelect } from 'antd'; +import { Form, TreeSelect, Row, Col } from 'antd'; // ant_components import BIInput from '@/ant_components/BIInput'; import BISelect from '@/ant_components/BISelect'; @@ -21,6 +22,19 @@ import styles from './index.less'; // 工具 /* eslint-disable no-underscore-dangle */ // 基础搜索组件 +// mode分为page 为页面模式下的搜索框, modal 弹框模式下搜索组件 + + +const formItemLayout = { + labelCol: { + xs: { span: 24 }, + sm: { span: 4 }, + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 20 }, + }, +}; class SearchView extends React.Component { _renderItem = (col) => { const { type, placeholder, options = [], style, disabled, className, render, componentAttr = {}, key } = col; @@ -36,26 +50,26 @@ class SearchView extends React.Component { dropdownRender={ componentAttr.dropdownStatus ? (menu) => { - return ( -
-
- { - this.props.form.setFieldsValue({ - [`${key}`]: options.map((item) => { - return `${item.id}`; - }), - }); - }} - onMouseDown={(e) => { - e.preventDefault(); - }} - > - 全选 + return ( +
+
+ { + this.props.form.setFieldsValue({ + [`${key}`]: options.map((item) => { + return `${item.id}`; + }), + }); + }} + onMouseDown={(e) => { + e.preventDefault(); + }} + > + 全选 - {/* 反选功能 */} - {/* { const result = @@ -75,11 +89,11 @@ class SearchView extends React.Component { > 反选 */} -
- {menu} -
- ); - } +
+ {menu} +
+ ); + } : undefined } dropdownMenuStyle={componentAttr.dropdownStatus ? { borderTop: '1px solid #E1E1E1' } : null} @@ -211,34 +225,34 @@ class SearchView extends React.Component { dropdownRender={ componentAttr.dropdownStatus ? (menu) => { - return ( -
-
- { - const res = await componentAttr.request(); - const result = res.data.list.map((item) => { - return { - value: item.index, - label: item.value, - }; - }); - this.props.form.setFieldsValue({ - [`${key}`]: result, - }); - }} - onMouseDown={(e) => { - e.preventDefault(); - }} - > - 全选 + return ( +
+
+ { + const res = await componentAttr.request(); + const result = res.data.list.map((item) => { + return { + value: item.index, + label: item.value, + }; + }); + this.props.form.setFieldsValue({ + [`${key}`]: result, + }); + }} + onMouseDown={(e) => { + e.preventDefault(); + }} + > + 全选 -
- {menu} -
- ); - } +
+ {menu} +
+ ); + } : undefined } dropdownMenuStyle={componentAttr.dropdownStatus ? { borderTop: '1px solid #E1E1E1' } : null} @@ -312,6 +326,18 @@ class SearchView extends React.Component { newData[key] = dates; this.props.form.setFieldsValue(newData); }; + _renderModalForm = (col) => { + const { label, type, key, checkOption = [], className } = col; + const { getFieldDecorator } = this.props.form; + return ( + + {type === 'custom' + ? this._renderItem(col) + : getFieldDecorator(key, checkOption)(this._renderItem(col))} + + ) + + } _renderCol = (col) => { const { label, type, key, checkOption, className } = col; @@ -319,6 +345,10 @@ class SearchView extends React.Component { if (!key && type !== 'custom') { return null; } + if (this.props.modal === 'modal') { + return this._renderModalForm(col); + } + return (
{!!label &&
{label}
} @@ -336,11 +366,11 @@ class SearchView extends React.Component { _renderRow = (arr, index) => { const len = arr.length; let colClass = styles.colWrap; - if (len > 1) { + if (len > 0) { colClass += ` ${styles[`_${len}`]}`; } return ( -
+
{arr.map((col, i) => { return (
@@ -351,14 +381,22 @@ class SearchView extends React.Component {
); }; + /** + * 弹框模式下渲染数据,使用以为数组,平铺展示 + */ + _renderModalItem = (col = {}) => { + if (Object.prototype.toString.call(col) !== '[object Object]') return null; + return this._renderModalForm(col) + + } render() { - const { style, searchCols = [], advancedSearchCols = [] } = this.props; + const { style, searchCols = [], advancedSearchCols = [], modal } = this.props; return ( - - {/* 基础搜索 */} + + {/* 基础搜索 modal模式下为对象,非modal下为数组 */} {searchCols.map((arr, index) => { - return this._renderRow(arr, index); + return modal === 'modal' ? this._renderModalItem(arr) : this._renderRow(arr, index); })} {/* 高级搜索 */} {Array.isArray(advancedSearchCols) && advancedSearchCols.length > 0 ? ( diff --git a/components/SearchView/index.less b/components/SearchView/index.less index 54371fa..659bf9e 100644 --- a/components/SearchView/index.less +++ b/components/SearchView/index.less @@ -24,7 +24,9 @@ .colWrap { display: inline-block; vertical-align: middle; - + &._1 { + width: 100%; + } &._2 { width: 50%; } @@ -81,6 +83,9 @@ } } } + .modalRowWrap{ + margin-bottom: 0px; + } } .chooseAll { @@ -89,3 +94,11 @@ //background-color: blue; //border-top: 1px solid red; } +.formItem{ + display: flex; + align-items: center; + justify-content: flex-start; + :global .ant-form-item-control{ + line-height: 1.2; + } +} \ No newline at end of file -- 2.21.0