@cainiaofe/cn-ui-m
Version:
212 lines (211 loc) • 12.7 kB
JavaScript
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,
};