UNPKG

@cainiaofe/cn-ui-m

Version:
212 lines (211 loc) 12.7 kB
import { __assign } from "tslib"; import $i18n from "../../locales/i18n"; import './index.scss'; import * as React from 'react'; import classNames from 'classnames'; import { toJS } from '@formily/reactive'; import { createForm, onFieldValueChange } from '@formily/core'; import { FormProvider } from '@formily/react'; import { CnButton } from "../cn-button"; import { CnDrawer } from "../cn-drawer"; import { CnIcon } from "../cn-icon"; import { useDeepCompareEffect } from 'ahooks'; import { useSplitFilter } from './quick-filter-render'; import { CnButtonGroup } from '../cn-button-group'; import { withNativeProps } from '@cainiaofe/cn-ui-common'; import get from 'lodash/get'; import { useSplitSchema } from './schema-quick-filter-render'; import { CnFormLayout } from "../../form/cn-form-layout"; import debounce from 'lodash/debounce'; import isEqual from 'lodash/isEqual'; import { hasTruthyValue } from './utils'; export function CnFilter(props) { var form = props.form, _a = props.formProps, formProps = _a === void 0 ? {} : _a, isSticky = props.isSticky, onChange = props.onChange, submit = props.onSubmit, reset = props.onReset, propsOnSearch = props.onSearch, children = props.children, hiddenFilterButton = props.hiddenFilterButton, components = props.components, schema = props.schema, positionFix = props.positionFix, rightSlot = props.rightSlot, type = props.type; var isInCard = React.useMemo(function () { return ['card-level', 'card-level-subtitle-action'].includes(type); }, [type]); var isInCardSubAction = React.useMemo(function () { return type === 'card-level-subtitle-action'; }, [type]); // @ts-ignore var _b = React.useState({}), forceUpdate = _b[1]; var _c = React.useState(false), drawerVisible = _c[0], setDrawerVisible = _c[1]; var _d = React.useState(false), isOverflow = _d[0], setIsOverflow = _d[1]; // 是否包含有效查询条件,用于控制查询图标颜色 var _e = React.useState(false), hasValidParams = _e[0], setHasValidParams = _e[1]; var headerRef = React.createRef(); var normalizeChild = React.Children.toArray(children); var _f = useSplitFilter(normalizeChild), quickFilterChild = _f[0], quickWarpFilterChild = _f[1], normalFilterChild = _f[2], searchChild = _f[3]; var _g = useSplitSchema({ schema: schema, isInCard: isInCard, components: components, isInCardSubAction: isInCardSubAction }), quickSchemaChild = _g[0], quickNoWrapSchemaChild = _g[1], normalSchemaChild = _g[2], searchSchemaChild = _g[3]; var valueChainEffects = React.useCallback(function (formIns) { onFieldValueChange('*', function (field, fieldValueChangeForm) { var _a; var _b = field.getState(), _c = _b.path, path = _c === void 0 ? '' : _c, value = _b.value, decorator = _b.decorator; var isSchemaQuick = get(decorator, '1.quick', false); // 兼容 PC => H5 一码多端情况,额外设定 mobileProps var fieldProps = (field.props || {}); if (fieldProps.quick || ((_a = fieldProps.mobileProps) === null || _a === void 0 ? void 0 : _a.quick) || isSchemaQuick) { var formValues = fieldValueChangeForm.getValuesIn(path); // 解决死循环 if (!isEqual(value, formValues)) { formIns.setValuesIn(path, value); } debounceSubmit(null); } var values = formIns.getValuesIn('*'); // proxy数据类型转成普通类型 onChange && onChange(toJS(values)); }); }, [onChange]); var formInstance = React.useMemo(function () { if (form) { form.addEffects('valueChainEffects', valueChainEffects); return form; } // formProps 处理逻辑 return createForm(__assign(__assign({}, formProps), { effects: valueChainEffects })); }, [form]); useDeepCompareEffect(function () { if (formProps.values) { Object.keys(formProps.values).forEach(function (valueKey) { var _a; formInstance.setValuesIn(valueKey, (_a = formProps.values) === null || _a === void 0 ? void 0 : _a[valueKey]); }); } }, [formProps.values, formInstance]); var hideDrawer = function () { setDrawerVisible(false); }; var onSearch = function () { var values = formInstance.getValuesIn('*'); propsOnSearch && propsOnSearch(toJS(values)); forceUpdate({}); }; var onSubmit = function (e) { e && e.preventDefault(); formInstance.submit(function (res) { if (hasTruthyValue(res) === true) { setHasValidParams(true); } if (hasTruthyValue(res) === false) { setHasValidParams(false); } submit && submit(toJS(res)); onSearch(); hideDrawer(); }); }; var debounceSubmit = debounce(onSubmit, 100); var onReset = function () { formInstance.reset(); reset && reset(); }; if (formInstance) { formInstance.filterSearch = onSubmit; } // 渲染右侧筛选按钮 var renderSearch = function () { if (hiddenFilterButton) { return null; } var dividerCls = classNames({ 'cn-ui-m-filter-btn-divider': !isOverflow, 'cn-ui-m-filter-btn-shadow': isOverflow, }); var hasNormalFilter = (normalSchemaChild === null || normalSchemaChild === void 0 ? void 0 : normalSchemaChild.length) || (normalFilterChild === null || normalFilterChild === void 0 ? void 0 : normalFilterChild.length); return hasNormalFilter || rightSlot ? (React.createElement("div", { className: classNames('cn-ui-m-filter-footer', { 'cn-ui-m-filter-footer-card--sub-action': isInCardSubAction, }) }, hasNormalFilter ? (React.createElement("div", { className: "cn-ui-m-filter-footer-search", onClick: function () { return setDrawerVisible(true); } }, (normalFilterChild === null || normalFilterChild === void 0 ? void 0 : normalFilterChild.length) && ((quickFilterChild === null || quickFilterChild === void 0 ? void 0 : quickFilterChild.length) || (quickWarpFilterChild === null || quickWarpFilterChild === void 0 ? void 0 : quickWarpFilterChild.length)) ? (React.createElement("div", { className: dividerCls })) : null, React.createElement(CnIcon, { className: classNames('cn-ui-m-filter-btn-icon', { 'cn-ui-m-filter-btn-active': hasValidParams, }), type: "icon-filter", size: "small" }), React.createElement("span", { className: classNames('cn-ui-m-filter-btn-text', { 'cn-ui-m-filter-btn-active': hasValidParams, }) }, $i18n.get({ id: 'Filter', dm: '筛选' })))) : null, rightSlot && (React.createElement("div", { className: "cn-ui-m-filter-right-slot" }, rightSlot)))) : null; }; var renderQuickField = function () { var _a, _b; var headerCls = classNames('cn-ui-m-filter-header', { 'cn-ui-m-filter-header-card-padding': isInCard, }); if ((quickFilterChild === null || quickFilterChild === void 0 ? void 0 : quickFilterChild.length) || (quickSchemaChild === null || quickSchemaChild === void 0 ? void 0 : quickSchemaChild.length)) { return (React.createElement("div", { ref: headerRef, className: headerCls }, quickFilterChild, quickSchemaChild)); } if (quickWarpFilterChild === null || quickWarpFilterChild === void 0 ? void 0 : quickWarpFilterChild.length) { return (React.createElement("div", { ref: headerRef, className: headerCls }, React.createElement("div", { className: classNames('cn-ui-m-filter-quick-filter-no-warp', { 'cn-ui-m-filter-quick-filter-no-warp-card-padding': isInCard, }), style: (_b = (_a = quickWarpFilterChild[0]) === null || _a === void 0 ? void 0 : _a.props) === null || _b === void 0 ? void 0 : _b.style }, quickWarpFilterChild[0]))); } return null; }; var renderQuickNoWrapField = function () { if (quickNoWrapSchemaChild === null || quickNoWrapSchemaChild === void 0 ? void 0 : quickNoWrapSchemaChild.length) { return (React.createElement("div", { className: "cn-ui-m-filter-no-warp" }, quickNoWrapSchemaChild)); } return (quickWarpFilterChild === null || quickWarpFilterChild === void 0 ? void 0 : quickWarpFilterChild.length) ? (React.createElement("div", { className: "cn-ui-m-filter-no-warp" }, quickWarpFilterChild.map(function (item, i) { var _a; if (i === 0 && !(quickFilterChild === null || quickFilterChild === void 0 ? void 0 : quickFilterChild.length)) { return null; } return (React.createElement("div", { key: i, className: "cn-ui-m-filter-quick-filter-no-warp-wrapper" }, React.createElement("div", { className: classNames('cn-ui-m-filter-quick-filter-no-warp', { 'cn-ui-m-filter-quick-filter-no-warp-card-padding': isInCard, }), style: (_a = item === null || item === void 0 ? void 0 : item.props) === null || _a === void 0 ? void 0 : _a.style }, item))); }))) : null; }; React.useEffect(function () { (function () { var _a, _b, _c, _d; var scrollWidth = (_b = (_a = headerRef === null || headerRef === void 0 ? void 0 : headerRef.current) === null || _a === void 0 ? void 0 : _a.firstElementChild) === null || _b === void 0 ? void 0 : _b.scrollWidth; var offsetWidth = (_d = (_c = headerRef === null || headerRef === void 0 ? void 0 : headerRef.current) === null || _c === void 0 ? void 0 : _c.firstElementChild) === null || _d === void 0 ? void 0 : _d.offsetWidth; if (scrollWidth > offsetWidth && !isOverflow) { setIsOverflow(true); } })(); }); return (React.createElement(FormProvider, { form: formInstance }, withNativeProps(props, React.createElement("div", { className: classNames(CN_UI_HASH_CLASS_NAME, 'cn-ui-m-filter', { 'cn-ui-m-filter-position-fix': isInCard ? false : positionFix, 'cn-ui-m-filter-sticky': isInCard ? false : isSticky, }), "data-testid": "cn-filter" }, searchChild, searchSchemaChild, (quickFilterChild === null || quickFilterChild === void 0 ? void 0 : quickFilterChild.length) || (quickWarpFilterChild === null || quickWarpFilterChild === void 0 ? void 0 : quickWarpFilterChild.length) || (quickSchemaChild === null || quickSchemaChild === void 0 ? void 0 : quickSchemaChild.length) || (quickNoWrapSchemaChild === null || quickNoWrapSchemaChild === void 0 ? void 0 : quickNoWrapSchemaChild.length) || !hiddenFilterButton ? (React.createElement("div", { className: classNames('cn-ui-m-filter-flex', { 'cn-ui-m-filter-flex-card--sub-action': isInCardSubAction, }) }, renderQuickField(), renderSearch())) : null, renderQuickNoWrapField())), React.createElement(CnDrawer, { visible: drawerVisible, title: $i18n.get({ id: 'Filter', dm: '筛选' }), placement: "bottom", onClose: hideDrawer, cancelProps: { children: null, visible: false, }, className: classNames('cn-ui-m-filter-drawer'), okProps: { children: null, visible: false, }, footer: React.createElement(CnButtonGroup, { fullWidth: true, size: "large" }, React.createElement(CnButton, { onClick: hideDrawer }, $i18n.get({ id: 'Cancel', dm: '取消' })), React.createElement(CnButton, { type: "secondary", onClick: onReset }, $i18n.get({ id: 'Reset', dm: '重置' })), React.createElement(CnButton, { type: "primary", onClick: function (e) { return onSubmit(e, 'normal'); } }, $i18n.get({ id: 'Query', dm: '查询' }))) }, React.createElement(CnFormLayout, { labelAlign: "left", wrapperAlign: "right" }, normalSchemaChild, normalFilterChild)))); } CnFilter.displayName = 'CnFilter'; CnFilter.defaultProps = { formProps: {}, isSticky: true, positionFix: true, };