@flatbiz/antd
Version:
380 lines (376 loc) • 17.8 kB
JavaScript
/*! @flatjs/forge MIT @flatbiz/antd */
import _PlusOutlined from '@ant-design/icons/es/icons/PlusOutlined.js';
import _CloseCircleFilled from '@ant-design/icons/es/icons/CloseCircleFilled.js';
import { classNames } from '@dimjs/utils/class-names/class-names';
import { a as _slicedToArray, c as _toConsumableArray, b as _objectSpread2 } from './_rollupPluginBabelHelpers-BYm17lo8.js';
import { hooks } from '@wove/react/hooks';
import { isArray } from '@dimjs/lang/is-array';
import { useState, useRef, useMemo, isValidElement } from 'react';
import { Form, Table, Space, message } from 'antd';
import { cloneState } from '@dimjs/model';
import { toArray, arrayReorder, isUndefinedOrNull } from '@flatbiz/utils';
import { B as ButtonWrapper } from './button-wrapper-l9FUsrWl.js';
import { fbaHooks } from './fba-hooks/index.js';
import { f as fbaUtils } from './fba-utils-Dfbczn1S.js';
import { F as FormItemWrapper } from './form-item-wrapper-BneADBjX.js';
import { T as TextSymbolWrapper } from './symbol-CX0y_DJ4.js';
import { T as TipsWrapper } from './tips-wrapper-Bf9nfZq3.js';
import { jsx, jsxs } from 'react/jsx-runtime';
/**
* 使用FormList实现可编辑表格
* ```
* 1. 必须在外部包裹Form组件
* 2. 表格数据源数组中必须存在唯一值字段,通过uidFieldKey配置
* 3. 可嵌套编辑,数据嵌套的节点名称可通过 childrenColumnName设置,默认:children
* 4. 行内需要联动逻辑可使用 column.render.operation.setCurrentRowTargetField 方法
* 5. 在多级编辑中,可通过 column.render.operation.level 判断当前行数据层级
* 6. 不存在多级的情况下,可使用DragEditableTablePro组件实现拖拽排序
* 7. 存在多级的情况下,可通过 column.render.operation.move 方法实现同一级内移动
*
* demo
* https://fex.qa.tcshuke.com/docs/admin/main/table/row-editable1
* https://fex.qa.tcshuke.com/docs/admin/main/table/row-editable2
* https://fex.qa.tcshuke.com/docs/admin/main/table/row-editable4
* ```
*/
var EditableTablePro = function EditableTablePro(props) {
var _props$tableProps2;
var form = Form.useFormInstance();
var _useState = useState([]),
_useState2 = _slicedToArray(_useState, 2),
expandedRowKeys = _useState2[0],
setExpandedRowKeys = _useState2[1];
var formListName = toArray(props.formListName);
var dataSourceUidMap = useRef({});
var dataSourceUidMapFt = useRef({});
var formListOperationRef = useRef();
var uidFieldKey = props.uidFieldKey;
var childrenColumnName = props.childrenColumnName || 'children';
var expandedIconLayout = props.expandedIconLayout || 'layout1';
var formListCompleteName = props.formListCompleteName || formListName;
var dataSource = Form.useWatch(formListCompleteName, form);
var _useState3 = useState(),
_useState4 = _slicedToArray(_useState3, 2),
showEmptyText = _useState4[0],
setShowEmptyText = _useState4[1];
var dataSourceFt = useMemo(function () {
if (!dataSource) return [];
var queryUidErrorFlag = false;
function deep(itemList, level, parentUid) {
for (var index = 0; index < itemList.length; index++) {
var item = itemList[index];
if (!item[uidFieldKey]) {
console.error(item, '数据中未查询到唯一值');
queryUidErrorFlag = true;
return;
} else {
dataSourceUidMapFt.current[item[uidFieldKey]] = {
level: level,
parentUid: parentUid,
index: index
};
dataSourceUidMap.current[item[uidFieldKey]] = item;
deep(item[childrenColumnName] || [], level + 1, item[uidFieldKey]);
}
}
}
dataSourceUidMapFt.current = {};
dataSourceUidMap.current = {};
deep(isArray(dataSource) ? dataSource : [], 1);
if (queryUidErrorFlag) {
var txt = "\u6570\u636E\u6E90\u4E2D\u5B58\u5728\u552F\u4E00\u503C\u3010".concat(uidFieldKey, "\u3011\u4E3A\u7A7A\u7684\u60C5\u51B5\uFF0C\u65E0\u6CD5\u6E32\u67D3\u8868\u683C");
void message.error(txt);
setShowEmptyText(txt);
return [];
}
return dataSource;
}, [childrenColumnName, dataSource, uidFieldKey]);
fbaHooks.useEffectCustom(function () {
setExpandedRowKeys(props.expandedRowKeys || []);
}, [JSON.stringify(props.expandedRowKeys || [])]);
var getFormItemName = hooks.useCallbackRef(function (record) {
var uid = record[uidFieldKey];
var target = dataSourceUidMapFt.current[uid];
var indexes = [];
while (target) {
indexes.push(target.index);
if (target.level === 1) {
break;
}
target = target.parentUid ? dataSourceUidMapFt.current[target.parentUid] : undefined;
}
var arr = [];
indexes.reverse().forEach(function (item, index) {
arr.push(item);
if (index < indexes.length - 1) {
arr.push(childrenColumnName);
}
});
return arr;
});
var addItem = hooks.useCallbackRef(function (uid, defaultValue, insertIndex) {
var target = dataSourceUidMap.current[uid];
if (target) {
if (target.level === 1) {
var _formListOperationRef;
/** 通过 formListOperation.add 可以使得 Form.List的 rules 生效 */
(_formListOperationRef = formListOperationRef.current) === null || _formListOperationRef === void 0 || _formListOperationRef.add(defaultValue, insertIndex);
return;
}
target[childrenColumnName] = target[childrenColumnName] || [];
if (insertIndex == undefined) {
target[childrenColumnName].push(defaultValue);
} else {
target[childrenColumnName].splice(insertIndex, 0, defaultValue);
}
var expandedRowKeysSet = new Set(expandedRowKeys);
expandedRowKeysSet.add(target[uidFieldKey]);
setExpandedRowKeys(_toConsumableArray(Array.from(expandedRowKeysSet)));
fbaUtils.setFormFieldsAndTriggerValuesChange(form, [{
name: formListCompleteName,
value: _toConsumableArray(dataSource)
}]);
}
});
var deleteItem = hooks.useCallbackRef(function (uid, index) {
var target = dataSourceUidMapFt.current[uid];
if (target.level === 1) {
var _formListOperationRef2;
/** 通过 formListOperation.remove 可以使得 Form.List的 rules 生效 */
(_formListOperationRef2 = formListOperationRef.current) === null || _formListOperationRef2 === void 0 || _formListOperationRef2.remove(index);
return;
}
var parentUid = target.parentUid;
if (!parentUid) {
dataSource.splice(index, 1);
} else {
var parentTarget = dataSourceUidMap.current[parentUid];
parentTarget[childrenColumnName].splice(index, 1);
if (parentTarget[childrenColumnName].length === 0) {
delete parentTarget[childrenColumnName];
}
}
fbaUtils.setFormFieldsAndTriggerValuesChange(form, [{
name: formListCompleteName,
value: cloneState(dataSource)
}]);
});
var moveItem = hooks.useCallbackRef(function (uid, fromIndex, toIndex) {
if (fromIndex === toIndex || toIndex < 0) return;
var target = dataSourceUidMapFt.current[uid];
var parentUid = target.parentUid;
if (!parentUid) {
var result = arrayReorder(dataSource, fromIndex, toIndex);
fbaUtils.setFormFieldsAndTriggerValuesChange(form, [{
name: formListCompleteName,
value: result
}]);
} else {
var parentTarget = dataSourceUidMap.current[parentUid];
parentTarget[childrenColumnName] = arrayReorder(parentTarget[childrenColumnName], fromIndex, toIndex);
fbaUtils.setFormFieldsAndTriggerValuesChange(form, [{
name: formListCompleteName,
value: _toConsumableArray(dataSource)
}]);
}
});
var setCurrentRowTargetField = hooks.useCallbackRef(function (formItemPrevName, dataIndexConfigs) {
fbaUtils.setFormFieldsAndTriggerValuesChange(form, dataIndexConfigs.map(function (item) {
return {
name: [].concat(_toConsumableArray(formListCompleteName), _toConsumableArray(formItemPrevName), _toConsumableArray(toArray(item.name))),
value: item.value
};
}));
});
var setCurrentRowChildrenValue = hooks.useCallbackRef(function (formItemPrevName, value) {
setCurrentRowTargetField(formItemPrevName, [{
name: childrenColumnName,
value: value
}]);
});
var validateRowFields = hooks.useCallbackRef(function (formItemPrevName, nameList) {
return new Promise(function ($return, $error) {
return Promise.resolve(form.validateFields(nameList.map(function (item) {
return [].concat(_toConsumableArray(formItemPrevName), _toConsumableArray(toArray(item)));
}))).then(function ($await_1) {
try {
return $return();
} catch ($boundEx) {
return $error($boundEx);
}
}, $error);
});
});
var columns = useMemo(function () {
return props.columns.map(function (column) {
var _column$formItemProps;
var title = column.title;
var support = /*#__PURE__*/isValidElement(title) || typeof title === 'string';
var titleRender = title;
if (column.tipsWrapperProps && support) {
if (typeof column.tipsWrapperProps === 'string') {
titleRender = /*#__PURE__*/jsx(TipsWrapper, {
tipType: "popover",
popoverProps: {
content: column.tipsWrapperProps
},
children: title
});
} else {
titleRender = /*#__PURE__*/jsx(TipsWrapper, _objectSpread2(_objectSpread2({}, column.tipsWrapperProps), {}, {
children: title
}));
}
}
var required = column.required;
if (!required && typeof column.formItemProps === 'object' && (_column$formItemProps = column.formItemProps.rules) !== null && _column$formItemProps !== void 0 && _column$formItemProps.length) {
required = !!column.formItemProps.rules.find(function (item) {
return !!item['required'];
});
}
return _objectSpread2(_objectSpread2({
onCell: function onCell() {
var _props$tableProps;
return {
valign: ((_props$tableProps = props.tableProps) === null || _props$tableProps === void 0 ? void 0 : _props$tableProps.cellVerticalAlign) || 'middle'
};
}
}, column), {}, {
title: required ? /*#__PURE__*/jsx(TextSymbolWrapper, {
style: {
marginLeft: column.align === 'center' ? undefined : 10
},
text: titleRender,
position: "before",
symbolType: "required"
}) : titleRender,
render: function render(value, record, index) {
var _column$render2;
if (isUndefinedOrNull(column.render)) {
return value;
}
var uid = record[uidFieldKey];
var dataIndex = toArray(column['dataIndex']);
var formItemPrevName = getFormItemName(record);
var dataSourceTarget = dataSourceUidMapFt.current[uid];
var editable = typeof (column === null || column === void 0 ? void 0 : column.editable) === 'function' ? column === null || column === void 0 ? void 0 : column.editable(record, index) : column === null || column === void 0 ? void 0 : column.editable;
var tableRowFormItemCompleteName = [].concat(_toConsumableArray(formListCompleteName), _toConsumableArray(formItemPrevName));
var renderOperationProps = {
editable: editable,
add: addItem.bind(null, uid),
remove: deleteItem.bind(null, uid),
move: moveItem.bind(null, uid),
level: dataSourceTarget.level,
parentItem: dataSourceTarget.parentUid ? dataSourceUidMapFt.current[dataSourceTarget.parentUid] : null,
tableRowFormItemName: formItemPrevName,
tableRowFormItemCompleteName: tableRowFormItemCompleteName,
setCurrentRowTargetField: setCurrentRowTargetField.bind(null, formItemPrevName),
setCurrentRowChildrenValue: setCurrentRowChildrenValue.bind(null, formItemPrevName),
validateRowFields: validateRowFields.bind(null, tableRowFormItemCompleteName)
};
if (editable === true) {
var _formItemProps, _formItemProps2, _column$render;
var formItemProps = typeof column.formItemProps === 'function' ? column.formItemProps(value, record, index, renderOperationProps) : column.formItemProps;
if (!((_formItemProps = formItemProps) !== null && _formItemProps !== void 0 && (_formItemProps = _formItemProps.rules) !== null && _formItemProps !== void 0 && _formItemProps.length) && required) {
formItemProps = _objectSpread2(_objectSpread2({}, formItemProps), {}, {
rules: [{
required: true,
message: ''
}]
});
}
return /*#__PURE__*/jsx(FormItemWrapper, _objectSpread2(_objectSpread2({}, formItemProps), {}, {
name: [].concat(_toConsumableArray(formItemPrevName), _toConsumableArray(dataIndex)),
style: _objectSpread2({
marginBottom: 0
}, (_formItemProps2 = formItemProps) === null || _formItemProps2 === void 0 ? void 0 : _formItemProps2.style),
children: (_column$render = column.render) === null || _column$render === void 0 ? void 0 : _column$render.call(column, value, record, index, renderOperationProps)
}));
}
return (_column$render2 = column.render) === null || _column$render2 === void 0 ? void 0 : _column$render2.call(column, value, record, index, renderOperationProps);
}
});
});
}, [props.columns, (_props$tableProps2 = props.tableProps) === null || _props$tableProps2 === void 0 ? void 0 : _props$tableProps2.cellVerticalAlign, uidFieldKey, getFormItemName, formListCompleteName, addItem, deleteItem, moveItem, setCurrentRowTargetField, setCurrentRowChildrenValue, validateRowFields]);
var className = classNames('editable-table-pro', {
'editable-table-pro-layout1': expandedIconLayout === 'layout1'
}, props.className);
return /*#__PURE__*/jsx("div", {
className: className,
style: props.style,
children: /*#__PURE__*/jsx(Form.List, {
name: formListName,
rules: props.rules,
initialValue: props.initialValue,
children: function children(fields, formListOperation, _ref) {
var _props$tableBeforeAre, _props$tableProps3, _props$tableAfterArea;
var errors = _ref.errors;
formListOperationRef.current = formListOperation;
return /*#__PURE__*/jsxs("div", {
style: {
borderRadius: '6px',
border: errors !== null && errors !== void 0 && errors.length ? '1px solid #ff4d4f' : '1px solid transparent'
},
children: [(_props$tableBeforeAre = props.tableBeforeAreaRender) === null || _props$tableBeforeAre === void 0 ? void 0 : _props$tableBeforeAre.call(props, formListOperation, fields.length), /*#__PURE__*/jsx(Table, _objectSpread2(_objectSpread2({
scroll: {
x: 'max-content'
},
pagination: false,
size: "small"
}, props.tableProps), {}, {
locale: {
emptyText: showEmptyText ? /*#__PURE__*/jsxs(Space, {
size: 5,
style: {
color: '#ff4d4f'
},
children: [/*#__PURE__*/jsx(_CloseCircleFilled, {}), /*#__PURE__*/jsx("span", {
children: showEmptyText
})]
}) : undefined
},
expandable: _objectSpread2(_objectSpread2({
expandedRowKeys: expandedRowKeys,
onExpandedRowsChange: function onExpandedRowsChange(expandedRowKeys) {
setExpandedRowKeys(expandedRowKeys);
}
}, (_props$tableProps3 = props.tableProps) === null || _props$tableProps3 === void 0 ? void 0 : _props$tableProps3.expandable), {}, {
childrenColumnName: childrenColumnName
}),
columns: columns,
dataSource: dataSourceFt,
rowKey: uidFieldKey
})), /*#__PURE__*/jsx(ButtonWrapper, {
block: true,
hidden: props.hiddenFooterBtn,
type: "dashed",
icon: /*#__PURE__*/jsx(_PlusOutlined, {}),
style: {
marginTop: 15
},
onClick: function onClick() {
var _props$addRowDefaultV;
var defaultValues = (_props$addRowDefaultV = props.addRowDefaultValues) === null || _props$addRowDefaultV === void 0 ? void 0 : _props$addRowDefaultV.call(props);
if (!(defaultValues !== null && defaultValues !== void 0 && defaultValues[uidFieldKey])) {
void message.error("\u65B0\u589E\u884C\u9ED8\u8BA4\u503C\u5FC5\u987B\u5305\u542B\u552F\u4E00\u503C\u5B57\u6BB5\u3010".concat(uidFieldKey, "\u3011\uFF0C\u901A\u8FC7 addRowDefaultValues \u8BBE\u7F6E"));
return;
}
formListOperation.add(defaultValues);
},
children: "\u65B0\u589E"
}), (_props$tableAfterArea = props.tableAfterAreaRender) === null || _props$tableAfterArea === void 0 ? void 0 : _props$tableAfterArea.call(props, formListOperation, fields.length), errors.length ? /*#__PURE__*/jsx(Form.ErrorList, {
errors: [/*#__PURE__*/jsx("div", {
style: {
color: '#ff4d4f',
padding: '5px'
},
children: errors
}, "0")]
}) : null]
});
}
})
});
};
export { EditableTablePro as E };
//# sourceMappingURL=editable-table-pro-DWoOUJrI.js.map