linkmore-design
Version:
🌈 🚀lm组件库。🚀
392 lines (379 loc) • 15 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _ahooks = require("ahooks");
var _classnames = _interopRequireDefault(require("classnames"));
var _castArray = _interopRequireDefault(require("lodash/castArray"));
var _isNil = _interopRequireDefault(require("lodash/isNil"));
var _react = _interopRequireWildcard(require("react"));
var _button = _interopRequireDefault(require("../../../button"));
var _dropdown = _interopRequireDefault(require("../../../dropdown"));
var _form = _interopRequireDefault(require("../../../form"));
var _iconFont = _interopRequireDefault(require("../../../icon-font"));
var _modal = _interopRequireDefault(require("../../../modal"));
var _constants = require("../../constants");
var _controls = _interopRequireDefault(require("../../controls"));
var _interface = require("../../interface");
var _SaveModal = _interopRequireDefault(require("./SaveModal"));
/** 自定义筛选配置项 */
const customConfig = {
label: 'label',
value: 'value',
options: 'data',
default: 'default'
};
const RenderChildren = ({
value,
onChange,
options,
open,
size,
fieldNames,
placeholder,
optionLabelProp
}) => {
const optionMap = (0, _react.useMemo)(() => {
if (!Array.isArray(options)) return new Map();
return new Map(options.map(option => [option[fieldNames.value], option[optionLabelProp] ?? option[fieldNames.label]]));
}, [options, fieldNames, optionLabelProp]);
const isExcitingValue = (0, _react.useMemo)(() => !(0, _isNil.default)(value), [value]);
const label = optionMap.has(value) ? optionMap.get(value) : value || placeholder;
return /*#__PURE__*/_react.default.createElement("div", {
className: (0, _classnames.default)(`${_constants.prefix}_custom_select`, {
expand: open,
small: size === 'small'
})
}, /*#__PURE__*/_react.default.createElement("div", {
className: `${_constants.prefix}_custom_select_label`
}, /*#__PURE__*/_react.default.createElement("span", null, label)), isExcitingValue ? /*#__PURE__*/_react.default.createElement(_iconFont.default, {
type: "lm-icon-a-shidia0shanchu",
onClick: e => {
e.stopPropagation();
onChange();
}
}) : /*#__PURE__*/_react.default.createElement("div", {
className: `${_constants.prefix}_custom_select_icon addon_after`
}, /*#__PURE__*/_react.default.createElement(_iconFont.default, {
type: "lm-icon-a-jiantoua2xialaxia"
})));
};
// 自定义筛选下拉框每一项的Render
const ItemBody = ({
item,
menuClick
}) => {
const isDefault = !!item.default;
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
className: "filter_item_content"
}, item.label, isDefault && `「默认」`), /*#__PURE__*/_react.default.createElement("div", {
className: "filter_item_operate",
onClick: e => e.stopPropagation()
}, item.value && /*#__PURE__*/_react.default.createElement("div", {
className: "icon_hover"
}, /*#__PURE__*/_react.default.createElement(_dropdown.default, {
placement: "bottomLeft",
trigger: ['click'],
menu: {
items: [{
key: 'rename',
label: '重命名'
}, {
key: 'default',
label: isDefault ? '取消默认' : '设为默认'
}, {
key: 'delete',
label: '删除'
}],
onClick: menuClick
}
}, /*#__PURE__*/_react.default.createElement(_iconFont.default, {
type: "lm-icon-a-tongyonga2gengduo"
})))));
};
// 自定义筛选界面展示内容
const CustomSelect = props => {
const {
size,
beforeSave,
isChange: filterChange,
dataSource,
onSelect
} = props;
const filterForm = _form.default.useFormInstance();
const custom = _form.default.useWatch(_constants.FIELD_ENUM.CUSTOM);
const basicFilter = _form.default.useWatch(_constants.FIELD_ENUM.BASIC);
const complexFilter = _form.default.useWatch(_constants.FIELD_ENUM.COMPLEX);
const [form] = _form.default.useForm();
const [open, onOpenChange] = (0, _react.useState)(false);
const [type, setVisible] = (0, _react.useState)(undefined);
// 接手customOptions 既可以自己管理,也可以被外部控制
const [customOptions, onSave] = (0, _ahooks.useControllableValue)(props, {
defaultValue: [],
valuePropName: 'customOptions',
trigger: 'onSave'
});
const getSaveFilter = (0, _ahooks.useMemoizedFn)(() => {
const getExcitingValue = conditions => {
if (!Array.isArray(conditions)) return [];
return conditions?.filter(item => {
const excitingEmpty = ['empty', 'not_empty'].includes(item.operator);
return excitingEmpty || !(0, _isNil.default)(item.value);
});
};
const resetBasicFilter = {
...basicFilter,
queryType: _interface.QUERY_TYPE.BASIC,
conditions: getExcitingValue(basicFilter?.conditions)
};
const resetComplexFilter = {
...complexFilter,
queryType: _interface.QUERY_TYPE.COMPLEX,
conditions: getExcitingValue(complexFilter?.conditions)
};
return [resetBasicFilter, resetComplexFilter];
});
/** 是否存在筛选条件 */
const isExcitingConditions = (0, _react.useMemo)(() => {
const [excitingBasicFilter, excitingComplexFilter] = getSaveFilter();
const hasFilter = excitingBasicFilter[_constants.FIELD_ENUM.CONDITIONS]?.length;
const complexConditionsLen = excitingComplexFilter[_constants.FIELD_ENUM.CONDITIONS]?.length;
return hasFilter || !!complexConditionsLen;
}, [basicFilter, complexFilter]);
/** 是否触发了变动 */
const isChange = (0, _react.useMemo)(() => {
if (!isExcitingConditions) return false;
if (!custom) return false;
return filterChange;
}, [isExcitingConditions, custom, filterChange]);
/** 打开弹窗 */
const onOpenModal = (0, _ahooks.useMemoizedFn)(() => {
if (!isExcitingConditions) return;
form.resetFields();
let jumpType = custom ? _interface.MODAL_TYPE_ENUM.COVER : _interface.MODAL_TYPE_ENUM.APPEND;
setVisible(jumpType);
});
/** 保存筛选方案, 此处传入的changedValues是before处理后的数据 */
const handleOnSave = (0, _ahooks.useMemoizedFn)(async changedValue => {
let resultList = [];
// 处理默认的唯一性
if ([_interface.MODAL_TYPE_ENUM.APPEND, _interface.MODAL_TYPE_ENUM.RENAME].includes(type)) {
resultList = customOptions.reduce((pre, cur) => {
const isDefault = changedValue.default ? false : cur[customConfig.default];
const isEditing = cur[customConfig.value] === changedValue.value;
const obj = isEditing ? {
...cur,
...changedValue
} : {
...cur,
default: isDefault
};
return pre.concat(obj);
}, []);
}
// 追加数据(此时的默认已被处理)
if (type === _interface.MODAL_TYPE_ENUM.APPEND) {
resultList.push(changedValue);
}
// 覆盖操作, 保存新的数据
if (type === _interface.MODAL_TYPE_ENUM.COVER) {
resultList = customOptions.reduce((pre, cur) => pre.concat(cur[customConfig.value] === custom ? changedValue : cur), []);
}
await onSave(resultList, changedValue, type);
});
// 保存前置事件, 处理变化的数据
const handleBeforeSave = (0, _ahooks.useMemoizedFn)(async changedValue => {
try {
let param;
if (type === _interface.MODAL_TYPE_ENUM.APPEND) {
param = {
...changedValue,
value: Date.now(),
data: getSaveFilter()
};
}
if (type === _interface.MODAL_TYPE_ENUM.RENAME) {
const originOption = customOptions.find(option => option[customConfig.value] === changedValue.value);
param = {
...originOption,
...changedValue
};
}
if (type === _interface.MODAL_TYPE_ENUM.COVER) {
const originOption = customOptions.find(option => option[customConfig.value] === custom);
param = {
...originOption,
data: getSaveFilter()
};
}
const callback = await beforeSave?.(param, type);
const result = callback || param;
handleOnSave(result);
} catch (error) {
console.log('handleBeforeSave:', error);
}
});
const menuClick = (0, _ahooks.useMemoizedFn)(({
key
}, item) => {
onOpenChange(false);
if (key === 'delete') {
_modal.default.confirm({
title: '删除筛选方案',
content: /*#__PURE__*/_react.default.createElement("span", {
style: {
color: '#7E84A3',
fontSize: 12
}
}, "\u60A8\u786E\u5B9A\u8981\u5220\u9664\u6B64\u7B5B\u9009\u65B9\u6848\u5417\uFF1F"),
okText: '删除',
onOk: async close => {
const resultList = customOptions.filter(v => v?.[customConfig.value] !== item?.value);
if (item.value === custom) {
filterForm.setFieldValue(_constants.FIELD_ENUM.CUSTOM, undefined);
}
await onSave(resultList, item, 'delete');
close();
}
});
}
if (key === 'default') {
const resultList = customOptions.map(v => ({
...v,
default: v?.[customConfig.value] === item?.value ? !v[customConfig.default] : false
}));
const checked = resultList.find(v => v?.value === item?.value);
const resetItem = {
...item,
default: checked ? checked?.default : true
};
onSave(resultList, resetItem, 'default');
}
if (key === 'rename') {
form.setFieldsValue({
...item,
default: !!item.default
});
setVisible(_interface.MODAL_TYPE_ENUM.RENAME);
}
});
/** 检查数据回显是否能够匹配options的值 */
const checkMatch = (0, _ahooks.useMemoizedFn)((value, itemObj = {}) => {
if ((0, _isNil.default)(value)) return value;
if (!['select', 'checkbox', 'cascader'].includes(itemObj.type)) return value;
const fieldNames = {
label: 'label',
value: 'value',
children: 'children',
...itemObj.fieldNames
};
const options = itemObj.options || [];
const optionsMap = new Map(options.map(option => [option[fieldNames.value], option]));
if (['select'].includes(itemObj.type)) {
return optionsMap.has(value) ? value : undefined;
}
if (['checkbox'].includes(itemObj.type)) {
return value?.filter(valueKey => optionsMap.has(valueKey));
}
const toArrValue = Array.isArray(value) ? value : (0, _castArray.default)(value);
const isCheckedMultiple = toArrValue.every(Array.isArray);
// 匹配文本内容
const matchLabel = checkedKeys => {
let flag = checkedKeys;
checkedKeys.reduce((pre, cur) => {
const option = (pre || []).find(v => v[fieldNames.value] === cur);
if (!option) {
flag = undefined;
return [];
}
// 对于级联数据向子级查找
return option[fieldNames.children] || [];
}, options);
return flag;
};
// 对于级联多选,需要遍历匹配
if (isCheckedMultiple) {
const isMatch = toArrValue.every(matchLabel);
return isMatch ? toArrValue : toArrValue.filter(matchLabel);
}
return matchLabel(toArrValue);
});
const normalize = value => {
const option = customOptions.find(item => item[customConfig.value] === value) || {};
const conditionGroups = option[customConfig.options] || [];
const groupMap = new Map(conditionGroups.map(group => [group.queryType ?? _interface.QUERY_TYPE.COMPLEX, group]));
const basic = groupMap.has(_interface.QUERY_TYPE.BASIC) ? groupMap.get(_interface.QUERY_TYPE.BASIC) : {
[_constants.FIELD_ENUM.RELATION]: _constants.initialFieldsValue[_constants.DYNAMIC_ENUM.RELATION],
[_constants.FIELD_ENUM.CONDITIONS]: []
};
const complex = groupMap.has(_interface.QUERY_TYPE.COMPLEX) ? groupMap.get(_interface.QUERY_TYPE.COMPLEX) : {
[_constants.FIELD_ENUM.RELATION]: _constants.initialFieldsValue[_constants.DYNAMIC_ENUM.RELATION],
[_constants.FIELD_ENUM.CONDITIONS]: undefined
};
const originBasicConditions = filterForm.getFieldValue([_constants.FIELD_ENUM.BASIC, _constants.FIELD_ENUM.CONDITIONS]);
const resetBasicConditions = originBasicConditions?.map(item => {
const option = basic[_constants.FIELD_ENUM.CONDITIONS]?.find(v => v[_constants.DYNAMIC_ENUM.FIELD_NAME] === item[_constants.DYNAMIC_ENUM.FIELD_NAME]);
const matchedValue = checkMatch(option?.[_constants.DYNAMIC_ENUM.VALUE], item);
return {
...item,
[_constants.DYNAMIC_ENUM.VALUE]: matchedValue
};
});
const resetComplexConditions = complex[_constants.FIELD_ENUM.CONDITIONS]?.map(item => {
const option = dataSource?.find(v => v[_constants.DYNAMIC_ENUM.FIELD_NAME] === item[_constants.DYNAMIC_ENUM.FIELD_NAME]);
const matchedValue = checkMatch(item?.[_constants.DYNAMIC_ENUM.VALUE], {
...option,
...item
});
return {
...option,
...item,
value: matchedValue
};
});
filterForm.setFieldsValue({
[_constants.FIELD_ENUM.BASIC]: {
[_constants.FIELD_ENUM.RELATION]: basic[_constants.FIELD_ENUM.RELATION],
[_constants.FIELD_ENUM.CONDITIONS]: resetBasicConditions
},
[_constants.FIELD_ENUM.COMPLEX]: {
[_constants.FIELD_ENUM.RELATION]: complex[_constants.FIELD_ENUM.RELATION] || _constants.initialFieldsValue[_constants.DYNAMIC_ENUM.RELATION],
[_constants.FIELD_ENUM.CONDITIONS]: resetComplexConditions
}
});
return value;
};
return /*#__PURE__*/_react.default.createElement("div", {
className: `${_constants.prefix}_custom_select_wrapper`
}, /*#__PURE__*/_react.default.createElement(_form.default.Item, {
name: _constants.FIELD_ENUM.CUSTOM,
noStyle: true,
normalize: normalize
}, /*#__PURE__*/_react.default.createElement(_controls.default, {
type: "select",
options: customOptions,
placeholder: "\u4E0D\u9650",
size: size,
optionLabelProp: "render",
children: RenderChildren,
onChange: onSelect
})), /*#__PURE__*/_react.default.createElement(_button.default, {
icon: /*#__PURE__*/_react.default.createElement(_iconFont.default, {
type: "lm-icon-chucun"
}),
className: (0, _classnames.default)(`${_constants.prefix}_custom_addon`, isChange && 'addon_highlight'),
onClick: onOpenModal
}), /*#__PURE__*/_react.default.createElement(_SaveModal.default, {
open: !!type,
type: type,
form: form,
onTypeChange: setVisible,
onCancel: () => setVisible(undefined),
onSave: handleBeforeSave
}));
};
var _default = CustomSelect;
exports.default = _default;