@antdv-vue/pro-utils 0.0.0-stage → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/README.md +80 -2
  3. package/dist/autoFocusToFirstChild/index.d.ts +9 -0
  4. package/dist/autoFocusToFirstChild/index.js +36 -0
  5. package/dist/childrenToArray/index.d.ts +7 -0
  6. package/dist/childrenToArray/index.js +8 -0
  7. package/dist/components/CopyToClipboard/copy/index.d.ts +10 -0
  8. package/dist/components/CopyToClipboard/copy/index.js +84 -0
  9. package/dist/components/CopyToClipboard/copy/toggle-selection.d.ts +4 -0
  10. package/dist/components/CopyToClipboard/copy/toggle-selection.js +27 -0
  11. package/dist/components/CopyToClipboard/index.d.ts +14 -0
  12. package/dist/components/CopyToClipboard/index.js +13 -0
  13. package/dist/components/Draggable/Draggable.d.ts +62 -0
  14. package/dist/components/Draggable/Draggable.js +162 -0
  15. package/dist/components/Draggable/DraggableCore.d.ts +40 -0
  16. package/dist/components/Draggable/DraggableCore.js +149 -0
  17. package/dist/components/Draggable/index.d.ts +4 -0
  18. package/dist/components/Draggable/index.js +3 -0
  19. package/dist/components/Draggable/types.d.ts +30 -0
  20. package/dist/components/Draggable/types.js +1 -0
  21. package/dist/components/Draggable/utils/domFns.d.ts +36 -0
  22. package/dist/components/Draggable/utils/domFns.js +165 -0
  23. package/dist/components/Draggable/utils/getPrefix.d.ts +6 -0
  24. package/dist/components/Draggable/utils/getPrefix.js +31 -0
  25. package/dist/components/Draggable/utils/positionFns.d.ts +13 -0
  26. package/dist/components/Draggable/utils/positionFns.js +96 -0
  27. package/dist/components/Draggable/utils/shims.d.ts +7 -0
  28. package/dist/components/Draggable/utils/shims.js +19 -0
  29. package/dist/components/DropdownFooter/index.d.ts +20 -0
  30. package/dist/components/DropdownFooter/index.js +80 -0
  31. package/dist/components/DropdownFooter/style/index.d.ts +8 -0
  32. package/dist/components/DropdownFooter/style/index.js +18 -0
  33. package/dist/components/ErrorBoundary/index.d.ts +25 -0
  34. package/dist/components/ErrorBoundary/index.js +65 -0
  35. package/dist/components/FieldLabel/index.d.ts +31 -0
  36. package/dist/components/FieldLabel/index.js +212 -0
  37. package/dist/components/FieldLabel/style/index.d.ts +8 -0
  38. package/dist/components/FieldLabel/style/index.js +146 -0
  39. package/dist/components/FilterDropdown/index.d.ts +38 -0
  40. package/dist/components/FilterDropdown/index.js +91 -0
  41. package/dist/components/FilterDropdown/style/index.d.ts +8 -0
  42. package/dist/components/FilterDropdown/style/index.js +21 -0
  43. package/dist/components/FormItem/FormItemInput.d.ts +34 -0
  44. package/dist/components/FormItem/FormItemInput.js +163 -0
  45. package/dist/components/FormItem/ItemHolder.d.ts +58 -0
  46. package/dist/components/FormItem/ItemHolder.js +289 -0
  47. package/dist/components/FormItem/index.d.ts +64 -0
  48. package/dist/components/FormItem/index.js +591 -0
  49. package/dist/components/FormList/Field.d.ts +29 -0
  50. package/dist/components/FormList/Field.js +106 -0
  51. package/dist/components/FormList/FieldContext.d.ts +15 -0
  52. package/dist/components/FormList/FieldContext.js +11 -0
  53. package/dist/components/FormList/InternalField.d.ts +51 -0
  54. package/dist/components/FormList/InternalField.js +149 -0
  55. package/dist/components/FormList/ListContext.d.ts +12 -0
  56. package/dist/components/FormList/ListContext.js +11 -0
  57. package/dist/components/FormList/index.d.ts +36 -0
  58. package/dist/components/FormList/index.js +145 -0
  59. package/dist/components/FormList/interface.d.ts +9 -0
  60. package/dist/components/FormList/interface.js +1 -0
  61. package/dist/components/FormList/namePathType.d.ts +9 -0
  62. package/dist/components/FormList/namePathType.js +1 -0
  63. package/dist/components/FormList/utils/index.d.ts +15 -0
  64. package/dist/components/FormList/utils/index.js +37 -0
  65. package/dist/components/InlineErrorFormItem/InlineErrorFormItemPopover.d.ts +21 -0
  66. package/dist/components/InlineErrorFormItem/InlineErrorFormItemPopover.js +95 -0
  67. package/dist/components/InlineErrorFormItem/index.d.ts +14 -0
  68. package/dist/components/InlineErrorFormItem/index.js +44 -0
  69. package/dist/components/InlineErrorFormItem/style/index.d.ts +8 -0
  70. package/dist/components/InlineErrorFormItem/style/index.js +46 -0
  71. package/dist/components/LabelIconTip/index.d.ts +16 -0
  72. package/dist/components/LabelIconTip/index.js +79 -0
  73. package/dist/components/LabelIconTip/style/index.d.ts +8 -0
  74. package/dist/components/LabelIconTip/style/index.js +38 -0
  75. package/dist/components/ProFormContext/index.d.ts +51 -0
  76. package/dist/components/ProFormContext/index.js +11 -0
  77. package/dist/conversionMomentValue/index.d.ts +48 -0
  78. package/dist/conversionMomentValue/index.js +103 -0
  79. package/dist/dateArrayFormatter/index.d.ts +14 -0
  80. package/dist/dateArrayFormatter/index.js +38 -0
  81. package/dist/deepMerge/index.d.ts +4 -0
  82. package/dist/deepMerge/index.js +17 -0
  83. package/dist/genCopyable/index.d.ts +27 -0
  84. package/dist/genCopyable/index.js +82 -0
  85. package/dist/getFieldPropsOrFormItemProps/index.d.ts +18 -0
  86. package/dist/getFieldPropsOrFormItemProps/index.js +15 -0
  87. package/dist/getSlot/index.d.ts +8 -0
  88. package/dist/getSlot/index.js +11 -0
  89. package/dist/hooks/index.d.ts +9 -0
  90. package/dist/hooks/index.js +9 -0
  91. package/dist/hooks/useDebounceFn/index.d.ts +12 -0
  92. package/dist/hooks/useDebounceFn/index.js +34 -0
  93. package/dist/hooks/useDebounceValue/index.d.ts +12 -0
  94. package/dist/hooks/useDebounceValue/index.js +21 -0
  95. package/dist/hooks/useDocumentTitle/index.d.ts +10 -0
  96. package/dist/hooks/useDocumentTitle/index.js +12 -0
  97. package/dist/hooks/useEffect/index.d.ts +6 -0
  98. package/dist/hooks/useEffect/index.js +17 -0
  99. package/dist/hooks/useFetchData/index.d.ts +12 -0
  100. package/dist/hooks/useFetchData/index.js +35 -0
  101. package/dist/hooks/useLayoutEffect/index.d.ts +6 -0
  102. package/dist/hooks/useLayoutEffect/index.js +21 -0
  103. package/dist/hooks/useMemo/index.d.ts +6 -0
  104. package/dist/hooks/useMemo/index.js +13 -0
  105. package/dist/hooks/useState/index.d.ts +6 -0
  106. package/dist/hooks/useState/index.js +11 -0
  107. package/dist/index.d.ts +61 -0
  108. package/dist/index.js +58 -0
  109. package/dist/isBrowser/index.d.ts +4 -0
  110. package/dist/isBrowser/index.js +8 -0
  111. package/dist/isDropdownValueType/index.d.ts +4 -0
  112. package/dist/isDropdownValueType/index.js +8 -0
  113. package/dist/isImg/index.d.ts +5 -0
  114. package/dist/isImg/index.js +7 -0
  115. package/dist/isNil/index.d.ts +4 -0
  116. package/dist/isNil/index.js +6 -0
  117. package/dist/isUrl/index.d.ts +9 -0
  118. package/dist/isUrl/index.js +17 -0
  119. package/dist/merge/index.d.ts +9 -0
  120. package/dist/merge/index.js +20 -0
  121. package/dist/nanoid/index.d.ts +9 -0
  122. package/dist/nanoid/index.js +25 -0
  123. package/dist/normalizeProps/index.d.ts +6 -0
  124. package/dist/normalizeProps/index.js +6 -0
  125. package/dist/omitBoolean/index.d.ts +9 -0
  126. package/dist/omitBoolean/index.js +11 -0
  127. package/dist/omitUndefined/index.d.ts +5 -0
  128. package/dist/omitUndefined/index.js +11 -0
  129. package/dist/omitUndefinedAndEmptyArr/index.d.ts +4 -0
  130. package/dist/omitUndefinedAndEmptyArr/index.js +12 -0
  131. package/dist/parseValueToDay/index.d.ts +7 -0
  132. package/dist/parseValueToDay/index.js +21 -0
  133. package/dist/pickProFormItemProps/index.d.ts +34 -0
  134. package/dist/pickProFormItemProps/index.js +42 -0
  135. package/dist/pickProProps/index.d.ts +4 -0
  136. package/dist/pickProProps/index.js +14 -0
  137. package/dist/pro-utils.esm.js +3672 -0
  138. package/dist/proFieldParsingText/index.d.ts +25 -0
  139. package/dist/proFieldParsingText/index.js +100 -0
  140. package/dist/runFunction/index.d.ts +5 -0
  141. package/dist/runFunction/index.js +8 -0
  142. package/dist/stringify/index.d.ts +7 -0
  143. package/dist/stringify/index.js +10 -0
  144. package/dist/transformBooleanProps/index.d.ts +4 -0
  145. package/dist/transformBooleanProps/index.js +9 -0
  146. package/dist/transformKeySubmitValue/index.d.ts +24 -0
  147. package/dist/transformKeySubmitValue/index.js +200 -0
  148. package/dist/transformVueNodeType/index.d.ts +14 -0
  149. package/dist/transformVueNodeType/index.js +14 -0
  150. package/dist/typing.d.ts +562 -0
  151. package/dist/typing.js +1 -0
  152. package/dist/useEditableArray/components/CancelEditableAction.d.ts +47 -0
  153. package/dist/useEditableArray/components/CancelEditableAction.js +90 -0
  154. package/dist/useEditableArray/components/DeleteEditableAction.d.ts +33 -0
  155. package/dist/useEditableArray/components/DeleteEditableAction.js +63 -0
  156. package/dist/useEditableArray/components/SaveEditableAction.d.ts +33 -0
  157. package/dist/useEditableArray/components/SaveEditableAction.js +79 -0
  158. package/dist/useEditableArray/index.d.ts +66 -0
  159. package/dist/useEditableArray/index.js +584 -0
  160. package/dist/useEditableArray/typing.d.ts +130 -0
  161. package/dist/useEditableArray/typing.js +1 -0
  162. package/dist/useEditableMap/index.d.ts +32 -0
  163. package/dist/useEditableMap/index.js +147 -0
  164. package/dist/useMediaQuery/index.d.ts +44 -0
  165. package/dist/useMediaQuery/index.js +99 -0
  166. package/dist/useMediaQuery/query.d.ts +6 -0
  167. package/dist/useMediaQuery/query.js +17 -0
  168. package/dist/useMountMergeState/index.d.ts +11 -0
  169. package/dist/useMountMergeState/index.js +26 -0
  170. package/dist/usePrevious/index.d.ts +6 -0
  171. package/dist/usePrevious/index.js +11 -0
  172. package/dist/useRefFunction/index.d.ts +4 -0
  173. package/dist/useRefFunction/index.js +11 -0
  174. package/package.json +69 -3
@@ -0,0 +1,584 @@
1
+ import { useEffect } from "../hooks/useEffect/index.js";
2
+ import { useDebounceFn } from "../hooks/useDebounceFn/index.js";
3
+ import { usePrevious } from "../usePrevious/index.js";
4
+ import CancelEditableAction, { normalizeNamePath, recordKeyToString } from "./components/CancelEditableAction.js";
5
+ import DeleteEditableAction from "./components/DeleteEditableAction.js";
6
+ import SaveEditableAction from "./components/SaveEditableAction.js";
7
+ import { computed, createVNode, isVNode, mergeProps, shallowRef } from "vue";
8
+ import { get, useMergedState } from "@v-c/util";
9
+ import { message } from "antdv-next";
10
+ import { useIntl } from "@antdv-vue/pro-provider";
11
+ import { noteOnce } from "@v-c/util/dist/warning";
12
+ import useLazyKVMap from "antdv-next/dist/table/hooks/useLazyKVMap";
13
+ //#region src/useEditableArray/index.tsx
14
+ /**
15
+ * 扁平化记录树结构为 Map
16
+ */
17
+ function _isSlot(s) {
18
+ return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
19
+ }
20
+ function flattenRecordsToMap(records, getRowKey, childrenColumnName, parentKey, parentIndex) {
21
+ const kvMap = /* @__PURE__ */ new Map();
22
+ records.forEach((record, index) => {
23
+ const eachIndex = (parentIndex || 0) * 10 + index;
24
+ const recordKey = getRowKey(record, eachIndex).toString();
25
+ if (record && typeof record === "object" && childrenColumnName in record) flattenRecordsToMap(record[childrenColumnName] || [], getRowKey, childrenColumnName, recordKey, eachIndex).forEach((value, key) => kvMap.set(key, value));
26
+ const newRecord = {
27
+ ...record,
28
+ map_row_key: recordKey,
29
+ map_row_parentKey: parentKey
30
+ };
31
+ delete newRecord.children;
32
+ if (!parentKey) delete newRecord.map_row_parentKey;
33
+ kvMap.set(recordKey, newRecord);
34
+ });
35
+ return kvMap;
36
+ }
37
+ /**
38
+ * 重建树结构
39
+ */
40
+ function rebuildTreeStructure(map, childrenColumnName, action) {
41
+ const childrenMap = /* @__PURE__ */ new Map();
42
+ const result = [];
43
+ const addNewRecordToChildren = (fillChildren) => {
44
+ map.forEach((value) => {
45
+ if (value.map_row_parentKey != null && !value.map_row_key) {
46
+ const { map_row_parentKey, ...rest } = value;
47
+ const parentKeyStr = String(map_row_parentKey);
48
+ if (!childrenMap.has(parentKeyStr)) childrenMap.set(parentKeyStr, []);
49
+ if (fillChildren) childrenMap.get(parentKeyStr)?.push(rest);
50
+ }
51
+ });
52
+ };
53
+ addNewRecordToChildren(action === "top");
54
+ map.forEach((value) => {
55
+ if (value.map_row_parentKey != null && value.map_row_key) {
56
+ const { map_row_parentKey, map_row_key, isNewRecord, ...rest } = value;
57
+ const record = {
58
+ ...rest,
59
+ map_row_key
60
+ };
61
+ const parentKeyStr = map_row_parentKey != null ? String(map_row_parentKey) : null;
62
+ if (!parentKeyStr) return;
63
+ if (!childrenMap.has(parentKeyStr)) childrenMap.set(parentKeyStr, []);
64
+ if (isNewRecord && action === "top") childrenMap.get(parentKeyStr)?.unshift(record);
65
+ else childrenMap.get(parentKeyStr)?.push(record);
66
+ }
67
+ });
68
+ map.forEach((value) => {
69
+ if (value.map_row_parentKey != null && value.map_row_key) {
70
+ const { map_row_parentKey, map_row_key } = value;
71
+ const parentKeyStr = map_row_parentKey != null ? String(map_row_parentKey) : null;
72
+ if (!parentKeyStr) return;
73
+ const children = childrenMap.get(parentKeyStr);
74
+ if (children && children.length > 0) {
75
+ const recordIndex = children.findIndex((r) => {
76
+ const recordKey = r.map_row_key || r.id;
77
+ return String(recordKey) === String(map_row_key);
78
+ });
79
+ if (recordIndex >= 0 && childrenMap.has(map_row_key)) children[recordIndex] = {
80
+ ...children[recordIndex],
81
+ [childrenColumnName]: childrenMap.get(map_row_key)
82
+ };
83
+ }
84
+ }
85
+ });
86
+ addNewRecordToChildren(action === "update");
87
+ map.forEach((value) => {
88
+ if (!value.map_row_parentKey) {
89
+ const { map_row_key, ...rest } = value;
90
+ const record = map_row_key && childrenMap.has(map_row_key) ? {
91
+ ...rest,
92
+ [childrenColumnName]: childrenMap.get(map_row_key)
93
+ } : rest;
94
+ result.push(record);
95
+ }
96
+ });
97
+ return result;
98
+ }
99
+ /**
100
+ * 使用map 来删除数据,性能一般 但是准确率比较高
101
+ *
102
+ */
103
+ function editableRowByKey(keyProps, action) {
104
+ const { getRowKey, row, data, childrenColumnName = "children" } = keyProps;
105
+ const key = recordKeyToString(keyProps.key)?.toString();
106
+ const kvMap = flattenRecordsToMap(data, getRowKey, childrenColumnName);
107
+ if (action === "delete") kvMap.delete(key);
108
+ else if (action === "top" || action === "update") {
109
+ const existingRecord = kvMap.get(key);
110
+ if (existingRecord) kvMap.set(key, {
111
+ ...existingRecord,
112
+ ...row
113
+ });
114
+ else kvMap.set(key, {
115
+ ...row,
116
+ map_row_key: key,
117
+ map_row_parentKey: row.map_row_parentKey,
118
+ isNewRecord: true
119
+ });
120
+ }
121
+ return rebuildTreeStructure(kvMap, childrenColumnName, action);
122
+ }
123
+ function defaultActionRender(row, config) {
124
+ const { recordKey, newLineConfig, saveText, cancelText, deleteText } = config;
125
+ const saveRef = shallowRef();
126
+ return {
127
+ save: createVNode(SaveEditableAction, mergeProps({ "key": `save${recordKey}` }, config, {
128
+ "row": row,
129
+ "ref": saveRef
130
+ }), _isSlot(saveText) ? saveText : { default: () => [saveText] }),
131
+ delete: newLineConfig?.options.recordKey !== recordKey && deleteText ? createVNode(DeleteEditableAction, mergeProps({ "key": `delete${recordKey}` }, config, { "row": row }), _isSlot(deleteText) ? deleteText : { default: () => [deleteText] }) : void 0,
132
+ cancel: createVNode(CancelEditableAction, mergeProps({ "key": `cancel${recordKey}` }, config, { "row": row }), _isSlot(cancelText) ? cancelText : { default: () => [cancelText] }),
133
+ saveRef
134
+ };
135
+ }
136
+ /**
137
+ * 一个方便的hooks 用于维护编辑的状态
138
+ *
139
+ * @param props
140
+ */
141
+ function useEditableArray(props) {
142
+ const intl = useIntl();
143
+ const [messageApi, ContextHolder] = message.useMessage();
144
+ /**
145
+ * 点击开始编辑之前的保存数据用的
146
+ */
147
+ const preEditRow = shallowRef(null);
148
+ const preEditRows = shallowRef(/* @__PURE__ */ new Map());
149
+ const newLineRecordCache = shallowRef(void 0);
150
+ const dataSourceFormKeyMapRef = shallowRef(/* @__PURE__ */ new Map());
151
+ const getBusinessRowKey = (record) => props.getRowKey.value(record, -1);
152
+ /**
153
+ * 构建数据源 key 索引映射表
154
+ */
155
+ const buildDataSourceKeyIndexMap = () => {
156
+ const map = /* @__PURE__ */ new Map();
157
+ const formKeyMap = /* @__PURE__ */ new Map();
158
+ const loopGetKey = (dataSource, parentKey) => {
159
+ dataSource?.forEach((record, index) => {
160
+ const indexKey = parentKey == null ? index.toString() : `${parentKey}_${index}`;
161
+ const recordKey = recordKeyToString(props.getRowKey.value(record, -1));
162
+ if (recordKey == null) return;
163
+ map.set(indexKey, recordKey);
164
+ map.set(recordKey.toString(), indexKey);
165
+ formKeyMap.set(recordKey.toString(), indexKey);
166
+ const children = props.childrenColumnName?.value && record?.[props.childrenColumnName.value];
167
+ if (children) loopGetKey(children, indexKey);
168
+ });
169
+ };
170
+ loopGetKey(props.dataSource.value);
171
+ dataSourceFormKeyMapRef.value = formKeyMap;
172
+ return map;
173
+ };
174
+ const dataSourceKeyIndexMapRef = shallowRef(computed(() => buildDataSourceKeyIndexMap()).value);
175
+ const resolveFormRecordKey = (recordKey, fallbackIndex) => {
176
+ if (!props.tableName?.value) return recordKey;
177
+ const normalizedRecordKey = recordKeyToString(recordKey);
178
+ if (fallbackIndex != null) return fallbackIndex;
179
+ const cachedFormRecordKey = dataSourceFormKeyMapRef.value.get(normalizedRecordKey);
180
+ if (cachedFormRecordKey != null) return cachedFormRecordKey;
181
+ dataSourceKeyIndexMapRef.value = buildDataSourceKeyIndexMap();
182
+ return dataSourceFormKeyMapRef.value.get(normalizedRecordKey) ?? recordKey;
183
+ };
184
+ const newLineRecordRef = shallowRef(void 0);
185
+ useEffect(() => {
186
+ dataSourceKeyIndexMapRef.value = buildDataSourceKeyIndexMap();
187
+ }, [() => props.dataSource.value]);
188
+ useEffect(() => {
189
+ newLineRecordRef.value = newLineRecordCache.value;
190
+ }, [() => newLineRecordCache.value]);
191
+ const editableType = computed(() => props.type?.value || "single");
192
+ const [getRecordByKey] = useLazyKVMap(props.dataSource, "children", props.getRowKey);
193
+ const [editableKeys, setEditableRowKeys] = useMergedState([], {
194
+ value: computed(() => props.editableKeys.value),
195
+ onChange: props.onChange ? (keys) => {
196
+ props?.onChange?.(keys?.filter((key) => key !== void 0) ?? [], keys?.map((key) => getRecordByKey?.(key)).filter((key) => key !== void 0) ?? []);
197
+ } : void 0
198
+ });
199
+ const editableKeysRef = usePrevious(editableKeys);
200
+ /**
201
+ * 检查 key 是否在编辑列表中
202
+ */
203
+ const checkKeyInEditableList = (key, keysList) => keysList.includes(key);
204
+ /** 这行是不是编辑状态 */
205
+ const isEditable = (row) => {
206
+ const { getRowKey } = props;
207
+ const recordKeyWithIndex = getRowKey.value(row, row.index)?.toString?.();
208
+ const recordKey = getRowKey.value(row, -1)?.toString?.();
209
+ const stringEditableKeys = editableKeys.value?.map((key) => key?.toString());
210
+ const stringEditableKeysRef = editableKeysRef.value?.map((key) => key?.toString()) || [];
211
+ const preIsEditable = checkKeyInEditableList(recordKey, stringEditableKeysRef) || checkKeyInEditableList(recordKeyWithIndex, stringEditableKeysRef);
212
+ return {
213
+ recordKey,
214
+ isEditable: checkKeyInEditableList(recordKey, stringEditableKeys) || checkKeyInEditableList(recordKeyWithIndex, stringEditableKeys),
215
+ preIsEditable
216
+ };
217
+ };
218
+ /**
219
+ * 验证是否可以开始编辑
220
+ */
221
+ const validateCanStartEdit = () => {
222
+ if (editableKeys.value && editableKeys.value.length > 0 && editableType.value === "single" && props.onlyOneLineEditorAlertMessage !== false) {
223
+ messageApi.warning(props.onlyOneLineEditorAlertMessage || intl.value.getMessage({
224
+ id: "editableTable.onlyOneLineEditor",
225
+ defaultMessage: "只能同时编辑一行"
226
+ }));
227
+ return false;
228
+ }
229
+ return true;
230
+ };
231
+ /**
232
+ * 查找记录
233
+ */
234
+ const findRecordByKey = (recordKey) => {
235
+ const normalizedRecordKey = recordKeyToString(recordKey)?.toString();
236
+ return props.dataSource.value?.find((recordData) => {
237
+ return recordKeyToString(getBusinessRowKey(recordData))?.toString() === normalizedRecordKey;
238
+ }) ?? null;
239
+ };
240
+ /**
241
+ * 进入编辑状态
242
+ *
243
+ * @param recordKey
244
+ * @param record
245
+ */
246
+ const startEditable = async (recordKey, record) => {
247
+ if (!validateCanStartEdit()) return false;
248
+ if (!editableKeys.value?.some((key) => key === recordKey || key?.toString() === recordKey?.toString())) setEditableRowKeys(editableKeys.value ? [...editableKeys.value || [], recordKey] : [recordKey]);
249
+ preEditRow.value = record ?? findRecordByKey(recordKey) ?? null;
250
+ const recordKeyStr = recordKeyToString(recordKey)?.toString();
251
+ if (recordKeyStr) preEditRows.value.set(recordKeyStr, preEditRow.value);
252
+ return true;
253
+ };
254
+ /**
255
+ * 清理编辑状态
256
+ */
257
+ const clearEditableState = (recordKey) => {
258
+ const relayKey = recordKeyToString(recordKey);
259
+ const relayKeyStr = relayKey != null ? relayKey.toString() : null;
260
+ if (relayKeyStr == null) return;
261
+ setEditableRowKeys(editableKeys.value?.filter((key) => key?.toString() !== relayKeyStr && key !== relayKey) ?? []);
262
+ };
263
+ /**
264
+ * 保存或删除完成后仅结束编辑,不执行取消回调,也不恢复编辑前数据。
265
+ */
266
+ const finishEditable = async (recordKey) => {
267
+ const recordKeyStr = recordKeyToString(recordKey)?.toString();
268
+ const cacheRecordKey = newLineRecordCache.value?.options.recordKey;
269
+ const cacheRecordKeyStr = recordKeyToString(cacheRecordKey)?.toString();
270
+ if (recordKeyStr != null && cacheRecordKeyStr === recordKeyStr) newLineRecordCache.value = void 0;
271
+ if (recordKeyStr != null) preEditRows.value.delete(recordKeyStr);
272
+ if (preEditRow.value && recordKeyToString(props.getRowKey.value(preEditRow.value, -1))?.toString() === recordKeyStr) preEditRow.value = null;
273
+ clearEditableState(recordKey);
274
+ return true;
275
+ };
276
+ /**
277
+ * 退出编辑状态
278
+ *
279
+ * @param recordKey
280
+ * @param needReTry
281
+ */
282
+ const cancelEditable = async (recordKey, needReTry) => {
283
+ const relayKey = recordKeyToString(recordKey);
284
+ const relayKeyStr = relayKey != null ? relayKey.toString() : null;
285
+ const mappedKey = relayKeyStr != null ? dataSourceKeyIndexMapRef.value.get(relayKeyStr) : void 0;
286
+ const isInEditableSet = editableKeys.value?.some((key) => {
287
+ if (relayKeyStr == null) return false;
288
+ return key?.toString() === relayKeyStr || key === relayKey;
289
+ });
290
+ if (!isInEditableSet && mappedKey && (needReTry ?? true) && props.tableName?.value) return await cancelEditable(mappedKey, false);
291
+ if (props.onCancel && isInEditableSet) {
292
+ const record = findRecordByKey(Array.isArray(recordKey) ? recordKey[0] : recordKey);
293
+ const originRow = preEditRow.value;
294
+ const cacheRecordKey = newLineRecordCache.value?.options?.recordKey;
295
+ const cacheKey = cacheRecordKey != null ? recordKeyToString(cacheRecordKey) : null;
296
+ const cacheKeyStr = cacheKey != null ? cacheKey.toString() : null;
297
+ const newLineConfig = newLineRecordCache.value != null && cacheRecordKey != null && (cacheRecordKey === recordKey || cacheKeyStr != null && relayKeyStr != null && cacheKeyStr === relayKeyStr || cacheRecordKey?.toString() === recordKey?.toString() || String(cacheRecordKey) === String(recordKey)) ? newLineRecordCache.value : void 0;
298
+ try {
299
+ await props.onCancel(recordKey, record || newLineConfig?.defaultValue || {}, originRow || record || newLineConfig?.defaultValue || {}, newLineConfig);
300
+ } catch (error) {
301
+ console.error("onCancel error:", error);
302
+ }
303
+ }
304
+ if (newLineRecordCache.value) {
305
+ const cacheRecordKey = newLineRecordCache.value?.options.recordKey;
306
+ const cacheKeyStr = cacheRecordKey != null ? recordKeyToString(cacheRecordKey)?.toString() : null;
307
+ if (cacheRecordKey === recordKey || cacheKeyStr != null && relayKeyStr != null && cacheKeyStr === relayKeyStr || cacheRecordKey?.toString() === recordKey?.toString() || String(cacheRecordKey) === String(recordKey)) newLineRecordCache.value = void 0;
308
+ }
309
+ const originRow = preEditRow.value;
310
+ if (originRow && props.getRowKey.value(originRow, -1) === recordKey && isInEditableSet) {
311
+ try {
312
+ const form = (props.formProps?.formRef)?.value || props.form;
313
+ if (form) if (props.tableName?.value) {
314
+ const namePath = normalizeNamePath(props.tableName.value, resolveFormRecordKey(recordKey));
315
+ form.setFieldValue(namePath, originRow);
316
+ } else {
317
+ const recordKeyStr = recordKeyToString(recordKey)?.toString();
318
+ if (recordKeyStr) try {
319
+ form.resetFields([[recordKeyStr]]);
320
+ form.setFieldsValue({ [recordKeyStr]: void 0 });
321
+ } catch (error) {
322
+ console.warn("Failed to clear form fields in cancelEditable:", error);
323
+ }
324
+ }
325
+ } catch (error) {
326
+ console.warn("Failed to reset form fields in cancelEditable:", error);
327
+ }
328
+ preEditRow.value = null;
329
+ }
330
+ clearEditableState(recordKey);
331
+ return true;
332
+ };
333
+ const propsOnValuesChange = useDebounceFn(async (...rest) => {
334
+ props.onValuesChange?.(...rest);
335
+ }, 64);
336
+ /**
337
+ * 构建表单字段路径
338
+ */
339
+ const buildFormFieldPath = (recordKey) => {
340
+ return normalizeNamePath(props.tableName?.value, resolveFormRecordKey(recordKey));
341
+ };
342
+ /**
343
+ * 更新数据源中的编辑行
344
+ */
345
+ const updateDataSourceWithEditableRows = (dataSource, values) => {
346
+ let updatedDataSource = dataSource;
347
+ editableKeys.value?.forEach((eachRecordKey) => {
348
+ if (newLineRecordCache.value?.options.recordKey === eachRecordKey) return;
349
+ const recordKey = eachRecordKey.toString();
350
+ const editRow = get(values, buildFormFieldPath(recordKey));
351
+ if (!editRow) return;
352
+ updatedDataSource = editableRowByKey({
353
+ data: updatedDataSource,
354
+ getRowKey: getBusinessRowKey,
355
+ row: editRow,
356
+ key: recordKey,
357
+ childrenColumnName: props.childrenColumnName?.value || "children"
358
+ }, "update");
359
+ });
360
+ return updatedDataSource;
361
+ };
362
+ /**
363
+ * 获取当前编辑的行数据
364
+ */
365
+ const getCurrentEditRow = (value, values, dataSource) => {
366
+ const valueKeys = Object.keys(value || {});
367
+ if (valueKeys.length === 0) return newLineRecordCache.value?.defaultValue || {};
368
+ const recordKey = valueKeys.pop()?.toString() || "";
369
+ if (!recordKey) return newLineRecordCache.value?.defaultValue || {};
370
+ const fieldPath = buildFormFieldPath(recordKey);
371
+ const newLineRecordData = {
372
+ ...newLineRecordCache.value?.defaultValue,
373
+ ...get(values, fieldPath)
374
+ };
375
+ if (dataSourceKeyIndexMapRef.value.has(recordKeyToString(recordKey))) return dataSource.find((item, index) => {
376
+ return props.getRowKey.value(item, index)?.toString() === recordKey;
377
+ }) || newLineRecordData;
378
+ return newLineRecordData;
379
+ };
380
+ const onValuesChange = (value, values) => {
381
+ if (!props.onValuesChange) return;
382
+ const updatedDataSource = updateDataSourceWithEditableRows(props.dataSource.value, values);
383
+ const editRow = getCurrentEditRow(value, values, updatedDataSource);
384
+ propsOnValuesChange.run(editRow, updatedDataSource);
385
+ };
386
+ const saveRefsMap = shallowRef(/* @__PURE__ */ new Map());
387
+ /** 一个用来标志的set 提供了方便的 api 来去重什么的 */
388
+ useEffect(() => {
389
+ const editableKeysSet = new Set(editableKeys.value?.map((key) => key?.toString()) ?? []);
390
+ saveRefsMap.value.forEach((_, key) => {
391
+ if (!editableKeysSet.has(key?.toString())) saveRefsMap.value.delete(key);
392
+ });
393
+ }, [editableKeys]);
394
+ /**
395
+ * 获取保存引用
396
+ */
397
+ const getSaveRef = (recordKey) => {
398
+ const relayKey = recordKeyToString(recordKey);
399
+ return saveRefsMap.value.get(relayKey) || saveRefsMap.value.get(relayKey.toString());
400
+ };
401
+ /**
402
+ * 保存编辑行
403
+ *
404
+ * @param recordKey
405
+ * @param needReTry
406
+ */
407
+ const saveEditable = async (recordKey, needReTry) => {
408
+ const relayKey = recordKeyToString(recordKey);
409
+ const relayKeyStr = relayKey?.toString();
410
+ const mappedKey = dataSourceKeyIndexMapRef.value.get(relayKeyStr);
411
+ if (!editableKeys.value?.some((key) => key?.toString() === relayKeyStr || key === relayKey) && mappedKey && (needReTry ?? true) && props.tableName?.value) return await saveEditable(mappedKey, false);
412
+ const saveRef = getSaveRef(recordKey);
413
+ if (!saveRef?.value) return false;
414
+ await saveRef.value.save();
415
+ clearEditableState(recordKey);
416
+ return true;
417
+ };
418
+ /**
419
+ * 验证是否可以新增记录
420
+ */
421
+ const validateCanAddRecord = (options) => {
422
+ if (options?.parentKey && !dataSourceKeyIndexMapRef.value.has(recordKeyToString(typeof options?.parentKey === "function" ? options?.parentKey() : options?.parentKey).toString())) {
423
+ console.warn("can't find record by key", options?.parentKey);
424
+ return false;
425
+ }
426
+ if (newLineRecordRef.value && props.onlyAddOneLineAlertMessage !== false) {
427
+ messageApi.warning(props.onlyAddOneLineAlertMessage || intl.value.getMessage({
428
+ id: "editableTable.onlyAddOneLine",
429
+ defaultMessage: "只能新增一行"
430
+ }));
431
+ return false;
432
+ }
433
+ if (!validateCanStartEdit()) return false;
434
+ return true;
435
+ };
436
+ /**
437
+ * 验证记录 key 是否有效
438
+ */
439
+ const validateRecordKey = (recordKey) => {
440
+ if (recordKey == null && recordKey !== 0 && recordKey !== "") {
441
+ noteOnce(false, "请设置 recordCreatorProps.record 并返回一个唯一的key \n https://procomponents.ant.design/components/editable-table#editable-%E6%96%B0%E5%BB%BA%E8%A1%8C");
442
+ throw new Error("请设置 recordCreatorProps.record 并返回一个唯一的key");
443
+ }
444
+ };
445
+ const addEditRecord = async (row, options) => {
446
+ if (!validateCanAddRecord(options)) return false;
447
+ const recordKey = props.getRowKey.value(row, -1);
448
+ validateRecordKey(recordKey);
449
+ const recordKeyStr = recordKeyToString(recordKey)?.toString();
450
+ if (recordKeyStr) preEditRows.value.set(recordKeyStr, null);
451
+ if (!editableKeys.value?.some((key) => key === recordKey || key?.toString() === recordKey?.toString())) setEditableRowKeys(editableKeys.value ? [...editableKeys.value, recordKey] : [recordKey]);
452
+ const parentKeyValue = typeof options?.parentKey === "function" ? options.parentKey() : options?.parentKey;
453
+ if (options?.newRecordType === "dataSource" || props.tableName?.value && options?.newRecordType !== "cache") {
454
+ const actionProps = {
455
+ data: props.dataSource.value,
456
+ getRowKey: getBusinessRowKey,
457
+ row: {
458
+ ...row,
459
+ map_row_parentKey: parentKeyValue ? recordKeyToString(parentKeyValue)?.toString() : void 0
460
+ },
461
+ key: recordKey,
462
+ childrenColumnName: props.childrenColumnName?.value || "children"
463
+ };
464
+ props.setDataSource(editableRowByKey(actionProps, options?.position === "top" ? "top" : "update"));
465
+ } else newLineRecordCache.value = {
466
+ defaultValue: row,
467
+ options: {
468
+ ...options,
469
+ parentKey: parentKeyValue,
470
+ recordKey
471
+ }
472
+ };
473
+ return true;
474
+ };
475
+ const saveText = props?.saveText || intl.value.getMessage({
476
+ id: "editableTable.action.save",
477
+ defaultMessage: "保存"
478
+ });
479
+ const deleteText = props?.deleteText || intl.value.getMessage({
480
+ id: "editableTable.action.delete",
481
+ defaultMessage: "删除"
482
+ });
483
+ const cancelText = props?.cancelText || intl.value.getMessage({
484
+ id: "editableTable.action.cancel",
485
+ defaultMessage: "取消"
486
+ });
487
+ const actionSave = async (recordKey, editRow, originRow, newLine) => {
488
+ const res = await props?.onSave?.(recordKey, editRow, originRow, newLine);
489
+ if (res === false) return res;
490
+ const { options } = newLine || newLineRecordRef.value || {};
491
+ if (!options?.parentKey && options?.recordKey === recordKey) if (options?.position === "top") props.setDataSource([editRow, ...props.dataSource.value]);
492
+ else props.setDataSource([...props.dataSource.value, editRow]);
493
+ else {
494
+ const actionProps = {
495
+ data: props.dataSource.value,
496
+ getRowKey: getBusinessRowKey,
497
+ row: options ? {
498
+ ...editRow,
499
+ map_row_parentKey: recordKeyToString((typeof options?.parentKey === "function" ? options.parentKey() : options?.parentKey) || "")?.toString()
500
+ } : editRow,
501
+ key: recordKey,
502
+ childrenColumnName: props.childrenColumnName?.value || "children"
503
+ };
504
+ props.setDataSource(editableRowByKey(actionProps, options?.position === "top" ? "top" : "update"));
505
+ }
506
+ await finishEditable(recordKey);
507
+ return res;
508
+ };
509
+ const actionDelete = async (recordKey, editRow) => {
510
+ const actionProps = {
511
+ data: props.dataSource.value,
512
+ getRowKey: getBusinessRowKey,
513
+ row: editRow,
514
+ key: recordKey,
515
+ childrenColumnName: props.childrenColumnName?.value || "children"
516
+ };
517
+ const res = await props?.onDelete?.(recordKey, editRow);
518
+ if (res === false) return false;
519
+ await finishEditable(recordKey);
520
+ props.setDataSource(editableRowByKey(actionProps, "delete"));
521
+ return res;
522
+ };
523
+ const actionCancel = async (recordKey, editRow, originRow, newLine) => await props?.onCancel?.(recordKey, editRow, originRow, newLine);
524
+ const existCustomActionRender = props.actionRender && typeof props.actionRender === "function";
525
+ const customActionRender = existCustomActionRender ? props.actionRender : () => {};
526
+ const actionRender = (row) => {
527
+ const key = props.getRowKey.value(row, -1);
528
+ const config = {
529
+ saveText,
530
+ cancelText,
531
+ deleteText,
532
+ addEditRecord,
533
+ recordKey: key,
534
+ formRecordKey: resolveFormRecordKey(key, row.index),
535
+ cancelEditable,
536
+ finishEditable,
537
+ index: row.index,
538
+ tableName: props.tableName?.value,
539
+ newLineConfig: newLineRecordCache.value,
540
+ onCancel: actionCancel,
541
+ onDelete: actionDelete,
542
+ onSave: actionSave,
543
+ editableKeys: editableKeys.value,
544
+ setEditableRowKeys,
545
+ preEditRow: preEditRow.value,
546
+ "onUpdate:preEditRow": (_preEditRow) => preEditRow.value = _preEditRow,
547
+ preEditRows: preEditRows.value,
548
+ deletePopconfirmMessage: props.deletePopconfirmMessage || `${intl.value.getMessage({
549
+ id: "deleteThisLine",
550
+ defaultMessage: "删除此项"
551
+ })}?`
552
+ };
553
+ const renderResult = defaultActionRender(row, config);
554
+ if (props.tableName?.value) saveRefsMap.value.set(dataSourceKeyIndexMapRef.value.get(recordKeyToString(key)) || recordKeyToString(key), renderResult.saveRef);
555
+ else saveRefsMap.value.set(recordKeyToString(key), renderResult.saveRef);
556
+ if (existCustomActionRender) return customActionRender?.(row, config, {
557
+ save: renderResult.save,
558
+ delete: renderResult.delete,
559
+ cancel: renderResult.cancel
560
+ });
561
+ return [
562
+ renderResult.save,
563
+ renderResult.delete,
564
+ renderResult.cancel
565
+ ];
566
+ };
567
+ return {
568
+ messageContextHolder: ContextHolder,
569
+ editableKeys,
570
+ setEditableRowKeys,
571
+ isEditable,
572
+ actionRender,
573
+ startEditable,
574
+ cancelEditable,
575
+ addEditRecord,
576
+ saveEditable,
577
+ newLineRecord: newLineRecordCache,
578
+ preEditableKeys: editableKeysRef,
579
+ onValuesChange,
580
+ getRealIndex: props.getRealIndex
581
+ };
582
+ }
583
+ //#endregion
584
+ export { defaultActionRender, editableRowByKey, recordKeyToString, useEditableArray };