UNPKG

@antdv/pro-utils

Version:

@antdv/pro-utils

647 lines (646 loc) 26.2 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __objRest = (source, exclude) => { var target = {}; for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop]; if (source != null && __getOwnPropSymbols) for (var prop of __getOwnPropSymbols(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop]; } return target; }; var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; import { createVNode as _createVNode, mergeProps as _mergeProps } from "vue"; import { LoadingOutlined } from "@ant-design/icons-vue"; import { get, merge, set, useIntl } from "@antdv/pro-provider"; import { Form, Popconfirm } from "ant-design-vue"; import useLazyKVMap from "ant-design-vue/lib/table/hooks/useLazyKVMap"; import { computed, defineComponent, ref } from "vue"; import { noteOnce, useDebounceFn, useEffect, useInjectProFormContext, useMountMergeState } from "../index.mjs"; import { useDeepCompareEffectDebounce } from "../hooks/useDeepCompareEffect/index.mjs"; import { useMergedState } from "../hooks/useMergedState/index.mjs"; import { usePrevious } from "../hooks/usePrevious/index.mjs"; function warning(messageStr) { return (message.warn || message.warning)(messageStr); } function recordKeyToString(rowKey) { if (Array.isArray(rowKey)) return rowKey.join(","); return rowKey; } function editableRowByKey(keyProps, action) { var _a; const { getRowKey, row, data, childrenColumnName = "children" } = keyProps; const key = (_a = recordKeyToString(keyProps.key)) == null ? void 0 : _a.toString(); const kvMap = /* @__PURE__ */ new Map(); function dig(records, map_row_parentKey, map_row_index) { records.forEach((record, index) => { const eachIndex = (map_row_index || 0) * 10 + index; const recordKey = getRowKey(record, eachIndex).toString(); if (record && typeof record === "object" && childrenColumnName in record) { dig(record[childrenColumnName] || [], recordKey, eachIndex); } const newRecord = __spreadProps(__spreadValues({}, record), { map_row_key: recordKey, children: void 0, map_row_parentKey }); delete newRecord.children; if (!map_row_parentKey) { delete newRecord.map_row_parentKey; } kvMap.set(recordKey, newRecord); }); } if (action === "top") { kvMap.set(key, __spreadValues(__spreadValues({}, kvMap.get(key)), row)); } dig(data); if (action === "update") { kvMap.set(key, __spreadValues(__spreadValues({}, kvMap.get(key)), row)); } if (action === "delete") { kvMap.delete(key); } const fill = (map) => { const kvArrayMap = /* @__PURE__ */ new Map(); const kvSource = []; const fillNewRecord = (fillChildren = false) => { map.forEach((value) => { var _b; if (value.map_row_parentKey && !value.map_row_key) { const _a2 = value, { map_row_parentKey } = _a2, rest = __objRest(_a2, [ "map_row_parentKey" ]); if (!kvArrayMap.has(map_row_parentKey)) { kvArrayMap.set(map_row_parentKey, []); } if (fillChildren) { (_b = kvArrayMap.get(map_row_parentKey)) == null ? void 0 : _b.push(rest); } } }); }; fillNewRecord(action === "top"); map.forEach((value) => { var _b; if (value.map_row_parentKey && value.map_row_key) { const _a2 = value, { map_row_parentKey, map_row_key } = _a2, rest = __objRest(_a2, [ "map_row_parentKey", "map_row_key" ]); if (kvArrayMap.has(map_row_key)) { rest[childrenColumnName] = kvArrayMap.get(map_row_key); } if (!kvArrayMap.has(map_row_parentKey)) { kvArrayMap.set(map_row_parentKey, []); } (_b = kvArrayMap.get(map_row_parentKey)) == null ? void 0 : _b.push(rest); } }); fillNewRecord(action === "update"); map.forEach((value) => { if (!value.map_row_parentKey) { const _a2 = value, { map_row_key } = _a2, rest = __objRest(_a2, [ "map_row_key" ]); if (map_row_key && kvArrayMap.has(map_row_key)) { const item = __spreadProps(__spreadValues({}, rest), { [childrenColumnName]: kvArrayMap.get(map_row_key) }); kvSource.push(item); return; } kvSource.push(rest); } }); return kvSource; }; return fill(kvMap); } const SaveEditableAction = defineComponent((props, { expose, slots }) => { const context = useInjectProFormContext(); const form = Form.useFormInstance(); const [loading, setLoading] = useMountMergeState(false); const save = () => __async(void 0, null, function* () { var _a, _b, _c; try { const isMapEditor = props.editorType === "Map"; const namePath = [props.tableName, Array.isArray(props.recordKey) ? props.recordKey[0] : props.recordKey].map((key) => key == null ? void 0 : key.toString()).flat(1).filter(Boolean); setLoading(true); yield form.validateFields(namePath, { recursive: true }); const fields = ((_b = (_a = context == null ? void 0 : context.formMethods) == null ? void 0 : _a.getFieldFormatValue) == null ? void 0 : _b.call(_a, namePath)) || form.getFieldValue(namePath); if (Array.isArray(props.recordKey) && props.recordKey.length > 1) { const [, ...recordKeyPath] = props.recordKey; const curValue = get(fields, recordKeyPath); set(fields, recordKeyPath, curValue); } const data = isMapEditor ? set({}, namePath, fields) : fields; const res = yield (_c = props.onSave) == null ? void 0 : _c.call( props, props.recordKey, // 如果是 map 模式,fields 就是一个值,所以需要set 到对象中 // 数据模式 fields 是一个对象,所以不需要 merge({}, props.row, data), props.row, props.newLineConfig ); setLoading(false); return res; } catch (error) { console.log(error); setLoading(false); throw error; } }); expose({ save }); return () => { var _a; const children = props.children || ((_a = slots.default) == null ? void 0 : _a.call(slots)); return _createVNode("a", { "key": "save", "onClick": (e) => __async(void 0, null, function* () { e.stopPropagation(); e.preventDefault(); try { yield save(); } catch (e2) { } }) }, [loading ? _createVNode(LoadingOutlined, { "style": { marginInlineEnd: `8px` } }, null) : null, children || "\u4FDD\u5B58"]); }; }, { props: ["editableKeys", "recordKey", "preEditRowRef", "index", "cancelEditable", "onSave", "onDelete", "deletePopconfirmMessage", "setEditableRowKeys", "newLineConfig", "tableName", "deleteText", "cancelText", "saveText", "editorType", "addEditRecord", "row", "children"] }); const DeleteEditableAction = ({ recordKey, onDelete, preEditRowRef, row, children, deletePopconfirmMessage }) => { const [loading, setLoading] = useMountMergeState(() => false); const onConfirm = () => __async(void 0, null, function* () { try { setLoading(true); const res = yield onDelete == null ? void 0 : onDelete(recordKey, row); setLoading(false); return res; } catch (e) { console.log(e); setLoading(false); return null; } finally { if (preEditRowRef) preEditRowRef.value = null; } }); return children !== false ? _createVNode(Popconfirm, { "key": "delete", "title": deletePopconfirmMessage, "onConfirm": () => onConfirm() }, { default: () => [_createVNode("a", null, [loading ? _createVNode(LoadingOutlined, { "style": { marginInlineEnd: `8px` } }, null) : null, children || "\u5220\u9664"])] }) : null; }; const CancelEditableAction = (props) => { const { recordKey, tableName, newLineConfig, editorType, onCancel, cancelEditable, row, cancelText, preEditRowRef } = props; const context = useInjectProFormContext(); const form = Form.useFormInstance(); return _createVNode("a", { "key": "cancel", "onClick": (e) => __async(void 0, null, function* () { var _a, _b, _c; e.stopPropagation(); e.preventDefault(); const isMapEditor = editorType === "Map"; const namePath = [tableName, recordKey].flat(1).filter(Boolean); const fields = ((_b = (_a = context == null ? void 0 : context.formMethods) == null ? void 0 : _a.getFieldFormatValue) == null ? void 0 : _b.call(_a, namePath)) || (form == null ? void 0 : form.getFieldValue(namePath)); const record = isMapEditor ? set({}, namePath, fields) : fields; const res = yield onCancel == null ? void 0 : onCancel(recordKey, record, row, newLineConfig); yield cancelEditable(recordKey); if ((preEditRowRef == null ? void 0 : preEditRowRef.value) !== null) { form.setFieldsValue(set({}, namePath, preEditRowRef == null ? void 0 : preEditRowRef.value)); } else { yield (_c = props.onDelete) == null ? void 0 : _c.call(props, recordKey, row); } if (preEditRowRef) preEditRowRef.value = null; return res; }) }, [cancelText || "\u53D6\u6D88"]); }; function defaultActionRender(row, config) { const { recordKey, newLineConfig, saveText, deleteText } = config; const saveRef = ref(); return { save: _createVNode(SaveEditableAction, _mergeProps({ "key": `save${recordKey}` }, config, { "row": row, "ref": saveRef }), { default: () => [saveText] }), saveRef, delete: (newLineConfig == null ? void 0 : newLineConfig.options.recordKey) !== recordKey ? _createVNode(DeleteEditableAction, _mergeProps({ "key": `delete${recordKey}` }, config, { "row": row }), { default: () => [deleteText] }) : void 0, cancel: _createVNode(CancelEditableAction, _mergeProps({ "key": `cancel${recordKey}` }, config, { "row": row }), null) }; } function useEditableArray(props) { const intl = useIntl(); const preEditRowRef = ref(null); const newLineRecordCache = ref(void 0); const resetMapRef = () => { const map = /* @__PURE__ */ new Map(); const loopGetKey = (dataSource, parentKey) => { dataSource == null ? void 0 : dataSource.forEach((record, index) => { var _a; const key = parentKey === void 0 || parentKey === null ? index.toString() : `${parentKey}_${index.toString()}`; map.set(key, recordKeyToString(props.getRowKey(record, -1))); map.set((_a = recordKeyToString(props.getRowKey(record, -1))) == null ? void 0 : _a.toString(), key); if (props.childrenColumnName && (record == null ? void 0 : record[props.childrenColumnName])) { loopGetKey(record[props.childrenColumnName], key); } }); }; loopGetKey(props.dataSource); return map; }; const initDataSourceKeyIndexMap = computed(() => resetMapRef()); const dataSourceKeyIndexMapRef = ref(initDataSourceKeyIndexMap.value); useDeepCompareEffectDebounce(() => { dataSourceKeyIndexMapRef.value = resetMapRef(); }, [props.dataSource]); const newLineRecordRef = computed(() => newLineRecordCache.value); const editableType = props.type || "single"; const [getRecordByKey] = useLazyKVMap(computed(() => props.dataSource), computed(() => "children"), computed(() => props.getRowKey)); const [editableKeys, setEditableRowKeys] = useMergedState([], { value: ref(props.editableKeys), onChange: props.onChange ? (keys) => { var _a, _b, _c; (_c = props == null ? void 0 : props.onChange) == null ? void 0 : _c.call( props, // 计算编辑的key (_a = keys == null ? void 0 : keys.filter((key) => key !== void 0)) != null ? _a : [], // 计算编辑的行 (_b = keys == null ? void 0 : keys.map((key) => getRecordByKey(key)).filter((key) => key !== void 0)) != null ? _b : [] ); } : void 0 }); const editableKeysSet = computed(() => { var _a; const keys = editableType === "single" ? (_a = editableKeys.value) == null ? void 0 : _a.slice(0, 1) : editableKeys.value; return new Set(keys); }); const editableKeysRef = usePrevious(editableKeys); const isEditable = (row) => { var _a, _b, _c, _d, _e, _f; const recordKeyOrIndex = (_b = (_a = props.getRowKey(row, row.index)) == null ? void 0 : _a.toString) == null ? void 0 : _b.call(_a); const recordKey = (_d = (_c = props.getRowKey(row, -1)) == null ? void 0 : _c.toString) == null ? void 0 : _d.call(_c); const stringEditableKeys = (_e = editableKeys.value) == null ? void 0 : _e.map((key) => key == null ? void 0 : key.toString()); const stringEditableKeysRef = ((_f = editableKeysRef.value) == null ? void 0 : _f.map((key) => key == null ? void 0 : key.toString())) || []; const preIsEditable = props.tableName && !!(stringEditableKeysRef == null ? void 0 : stringEditableKeysRef.includes(recordKey)) || !!(stringEditableKeysRef == null ? void 0 : stringEditableKeysRef.includes(recordKeyOrIndex)); return { recordKey, isEditable: props.tableName && (stringEditableKeys == null ? void 0 : stringEditableKeys.includes(recordKey)) || (stringEditableKeys == null ? void 0 : stringEditableKeys.includes(recordKeyOrIndex)), preIsEditable }; }; const startEditable = (recordKey, record) => { var _a, _b; if (editableKeysSet.value.size > 0 && editableType === "single" && props.onlyOneLineEditorAlertMessage !== false) { warning(props.onlyOneLineEditorAlertMessage || intl.getMessage("editableTable.onlyOneLineEditor", "\u53EA\u80FD\u540C\u65F6\u7F16\u8F91\u4E00\u884C")); return false; } editableKeysSet.value.add(recordKey); setEditableRowKeys(Array.from(editableKeysSet.value)); preEditRowRef.value = (_b = record != null ? record : (_a = props.dataSource) == null ? void 0 : _a.find((recordData, index) => { return props.getRowKey(recordData, index) === recordKey; })) != null ? _b : null; return true; }; const cancelEditable = (recordKey, needReTry) => __async(this, null, function* () { var _a; const relayKey = recordKeyToString(recordKey).toString(); const key = dataSourceKeyIndexMapRef.value.get(relayKey); if (!editableKeysSet.value.has(relayKey) && key && (needReTry != null ? needReTry : true) && props.tableName) { cancelEditable(key, false); return; } if (newLineRecordCache.value && ((_a = newLineRecordCache.value) == null ? void 0 : _a.options.recordKey) === recordKey) { newLineRecordCache.value = void 0; } editableKeysSet.value.delete(relayKey); editableKeysSet.value.delete(recordKeyToString(recordKey)); setEditableRowKeys(Array.from(editableKeysSet.value)); return true; }); const propsOnValuesChange = useDebounceFn((...rest) => __async(this, null, function* () { var _a; (_a = props.onValuesChange) == null ? void 0 : _a.call(props, ...rest); }), 64); const onValuesChange = (value, values) => { var _a, _b, _c; if (!props.onValuesChange) { return; } let { dataSource } = props; (_a = editableKeys.value) == null ? void 0 : _a.forEach((eachRecordKey) => { var _a2; if (((_a2 = newLineRecordCache.value) == null ? void 0 : _a2.options.recordKey) === eachRecordKey) return; const recordKey2 = eachRecordKey.toString(); const editRow2 = get(values, [props.tableName || "", recordKey2].flat(1).filter((key) => key || key === 0)); if (!editRow2) return; dataSource = editableRowByKey({ data: dataSource, getRowKey: props.getRowKey, row: editRow2, key: recordKey2, childrenColumnName: props.childrenColumnName || "children" }, "update"); }); const relayValue = value; const recordKey = (_b = Object.keys(relayValue || {}).pop()) == null ? void 0 : _b.toString(); const newLineRecordData = __spreadValues(__spreadValues({}, ((_c = newLineRecordCache == null ? void 0 : newLineRecordCache.value) == null ? void 0 : _c.defaultValue) || {}), get(values, [props.tableName || "", recordKey.toString()].flat(1).filter((key) => key || key === 0))); const editRow = dataSourceKeyIndexMapRef.value.has(recordKeyToString(recordKey)) ? dataSource.find((item, index) => { var _a2; const key = (_a2 = props.getRowKey(item, index)) == null ? void 0 : _a2.toString(); return key === recordKey; }) : newLineRecordData; propsOnValuesChange.run(editRow || newLineRecordData, dataSource); }; const saveRefsMap = ref(/* @__PURE__ */ new Map()); useEffect(() => { saveRefsMap.value.forEach((_ref, key) => { if (!editableKeysSet.value.has(key)) { saveRefsMap.value.delete(key); } }); }, computed(() => [saveRefsMap.value, editableKeysSet.value])); const saveEditable = (recordKey, needReTry) => __async(this, null, function* () { var _a; const relayKey = recordKeyToString(recordKey); const key = dataSourceKeyIndexMapRef.value.get(recordKey.toString()); if (!editableKeysSet.value.has(relayKey) && key && (needReTry != null ? needReTry : true) && props.tableName) { return yield saveEditable(key, false); } const saveRef = saveRefsMap.value.get(relayKey) || saveRefsMap.value.get(relayKey.toString()); try { yield (_a = saveRef == null ? void 0 : saveRef.value) == null ? void 0 : _a.save(); } catch (e) { return false; } editableKeysSet.value.delete(relayKey); editableKeysSet.value.delete(relayKey.toString()); setEditableRowKeys(Array.from(editableKeysSet.value)); return true; }); const addEditRecord = (row, options) => { var _a; if ((options == null ? void 0 : options.parentKey) && !dataSourceKeyIndexMapRef.value.has(recordKeyToString(options == null ? void 0 : options.parentKey).toString())) { console.warn("can't find record by key", options == null ? void 0 : options.parentKey); return false; } if (newLineRecordRef.value && props.onlyAddOneLineAlertMessage !== false) { warning(props.onlyAddOneLineAlertMessage || intl.getMessage("editableTable.onlyAddOneLine", "\u53EA\u80FD\u65B0\u589E\u4E00\u884C")); return false; } if (editableKeysSet.value.size > 0 && editableType === "single" && props.onlyOneLineEditorAlertMessage !== false) { warning(props.onlyOneLineEditorAlertMessage || intl.getMessage("editableTable.onlyOneLineEditor", "\u53EA\u80FD\u540C\u65F6\u7F16\u8F91\u4E00\u884C")); return false; } const recordKey = props.getRowKey(row, -1); if (!recordKey && recordKey !== 0) { noteOnce(!!recordKey, "\u8BF7\u8BBE\u7F6E recordCreatorProps.record \u5E76\u8FD4\u56DE\u4E00\u4E2A\u552F\u4E00\u7684key \n https://procomponents.ant.design/components/editable-table#editable-%E6%96%B0%E5%BB%BA%E8%A1%8C"); throw new Error("\u8BF7\u8BBE\u7F6E recordCreatorProps.record \u5E76\u8FD4\u56DE\u4E00\u4E2A\u552F\u4E00\u7684key"); } editableKeysSet.value.add(recordKey); setEditableRowKeys(Array.from(editableKeysSet.value)); if ((options == null ? void 0 : options.newRecordType) === "dataSource" || props.tableName) { const actionProps = { data: props.dataSource, getRowKey: props.getRowKey, row: __spreadProps(__spreadValues({}, row), { map_row_parentKey: (options == null ? void 0 : options.parentKey) ? (_a = recordKeyToString(options == null ? void 0 : options.parentKey)) == null ? void 0 : _a.toString() : void 0 }), key: recordKey, childrenColumnName: props.childrenColumnName || "children" }; props.setDataSource(editableRowByKey(actionProps, (options == null ? void 0 : options.position) === "top" ? "top" : "update")); } else { newLineRecordCache.value = { defaultValue: row, options: __spreadProps(__spreadValues({}, options), { recordKey }) }; } return true; }; const saveText = (props == null ? void 0 : props.saveText) || intl.getMessage("editableTable.action.save", "\u4FDD\u5B58"); const deleteText = (props == null ? void 0 : props.deleteText) || intl.getMessage("editableTable.action.delete", "\u5220\u9664"); const cancelText = (props == null ? void 0 : props.cancelText) || intl.getMessage("editableTable.action.cancel", "\u53D6\u6D88"); const actionSaveRef = (recordKey, editRow, originRow, newLine) => __async(this, null, function* () { var _a, _b, _c; const res = yield (_a = props == null ? void 0 : props.onSave) == null ? void 0 : _a.call(props, recordKey, editRow, originRow, newLine); yield cancelEditable(recordKey); const { options } = newLine || newLineRecordRef.value || {}; if (!(options == null ? void 0 : options.parentKey) && (options == null ? void 0 : options.recordKey) === recordKey) { if ((options == null ? void 0 : options.position) === "top") { props.setDataSource([editRow, ...props.dataSource]); } else { props.setDataSource([...props.dataSource, editRow]); } return res; } const actionProps = { data: props.dataSource, getRowKey: props.getRowKey, row: options ? __spreadProps(__spreadValues({}, editRow), { map_row_parentKey: (_c = recordKeyToString((_b = options == null ? void 0 : options.parentKey) != null ? _b : "")) == null ? void 0 : _c.toString() }) : editRow, key: recordKey, childrenColumnName: props.childrenColumnName || "children" }; props.setDataSource(editableRowByKey(actionProps, (options == null ? void 0 : options.position) === "top" ? "top" : "update")); yield cancelEditable(recordKey); return res; }); const actionDeleteRef = (recordKey, editRow) => __async(this, null, function* () { var _a; const actionProps = { data: props.dataSource, getRowKey: props.getRowKey, row: editRow, key: recordKey, childrenColumnName: props.childrenColumnName || "children" }; const res = yield (_a = props == null ? void 0 : props.onDelete) == null ? void 0 : _a.call(props, recordKey, editRow); yield cancelEditable(recordKey, false); props.setDataSource(editableRowByKey(actionProps, "delete")); return res; }); const actionCancelRef = (recordKey, editRow, originRow, newLine) => __async(this, null, function* () { var _a; const res = yield (_a = props == null ? void 0 : props.onCancel) == null ? void 0 : _a.call(props, recordKey, editRow, originRow, newLine); return res; }); const existCustomActionRender = props.actionRender && typeof props.actionRender === "function"; const customActionRender = existCustomActionRender ? props.actionRender : () => { }; const actionRender = (row) => { const key = props.getRowKey(row, row.index); const config = { saveText, cancelText, deleteText, addEditRecord, recordKey: key, cancelEditable, index: row.index, tableName: props.tableName, newLineConfig: newLineRecordCache.value, onCancel: actionCancelRef, onDelete: actionDeleteRef, onSave: actionSaveRef, editableKeys: editableKeys.value, setEditableRowKeys, preEditRowRef, deletePopconfirmMessage: props.deletePopconfirmMessage || `${intl.getMessage("deleteThisLine", "\u5220\u9664\u6B64\u9879")}?` }; const renderResult = defaultActionRender(row, config); if (props.tableName) { saveRefsMap.value.set( dataSourceKeyIndexMapRef.value.get(recordKeyToString(key)) || recordKeyToString(key), // @ts-expect-error renderResult.saveRef ); } else { saveRefsMap.value.set(recordKeyToString(key), renderResult.saveRef); } if (existCustomActionRender) { return customActionRender == null ? void 0 : customActionRender(row, config, { save: renderResult.save, delete: renderResult.delete, cancel: renderResult.cancel }); } return [renderResult.save, renderResult.delete, renderResult.cancel]; }; return { editableKeys, setEditableRowKeys, isEditable, actionRender, startEditable, cancelEditable, addEditRecord, saveEditable, newLineRecord: newLineRecordCache, preEditableKeys: editableKeysRef, onValuesChange, getRealIndex: props.getRealIndex }; } export { DeleteEditableAction, SaveEditableAction, defaultActionRender, editableRowByKey, recordKeyToString, useEditableArray };