@hzab/list-render 1.10.19 → 1.10.20-alpha.0
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.
- package/README.md +10 -0
- package/package.json +3 -3
- package/src/EditArrayTable/index.less +11 -0
- package/src/EditArrayTable/index.tsx +198 -0
- package/src/components/Formily/{FormilyEditTable.tsx → --FormilyEditTable.tsx} +74 -3
- package/src/components/Formily/FormilyEditTable/EditTableCell.tsx +157 -0
- package/src/components/Formily/FormilyEditTable/EditTableRow.tsx +71 -0
- package/src/components/Formily/FormilyEditTable/index.tsx +229 -0
- package/src/components/Formily/FormilyEditTable/type.d.ts +6 -0
- package/src/components/Formily/FormilyEditTable/useTableFormilyContext.ts +17 -0
- package/src/components/Formily/SchemaToArrayTable.ts +266 -0
- package/src/list-render.jsx +8 -2
- package/src/table-render/index.jsx +117 -83
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { useEffect, useState,
|
|
1
|
+
import { useEffect, useState, useRef, forwardRef, useImperativeHandle, Fragment, useMemo } from "react";
|
|
2
2
|
import { Form, Table, Button, Popconfirm, Tooltip, Checkbox, Popover } from "antd";
|
|
3
3
|
import { QuestionCircleOutlined, FilterOutlined, SettingOutlined, MenuOutlined } from "@ant-design/icons";
|
|
4
4
|
import { SortableContainer, SortableElement, SortableHandle } from "react-sortable-hoc";
|
|
5
5
|
import { arrayMoveImmutable } from "array-move";
|
|
6
6
|
import _, { isFunction } from "lodash";
|
|
7
7
|
|
|
8
|
-
import { FormProvider, FormConsumer } from "@formily/react";
|
|
9
|
-
import { createForm, onFormValuesChange, onFieldValueChange } from "@formily/core";
|
|
10
|
-
|
|
11
8
|
import EnumRender from "@hzab/formily-result-utils/src/components/EnumRender";
|
|
12
9
|
import { SHOW_MODE_TYPES } from "@hzab/formily-result-utils/src/common/constant";
|
|
13
10
|
import { FormilyField } from "../components/Formily/FormilyField";
|
|
@@ -16,42 +13,64 @@ import { getColRender } from "../common/formily-utils";
|
|
|
16
13
|
import { getVal, getFieldList } from "../common/utils";
|
|
17
14
|
import { handleReactions } from "../common/handleReactions";
|
|
18
15
|
|
|
19
|
-
import { useEditTable
|
|
16
|
+
import { useEditTable } from "../components/Formily/FormilyEditTable";
|
|
17
|
+
import { EditTableRow } from "../components/Formily/FormilyEditTable/EditTableRow";
|
|
18
|
+
import { EditableCell } from "../components/Formily/FormilyEditTable/EditTableCell";
|
|
19
|
+
import { TableFormilyContext } from "../components/Formily/FormilyEditTable/useTableFormilyContext";
|
|
20
20
|
|
|
21
21
|
import "./index.less";
|
|
22
22
|
|
|
23
23
|
const scenario = "table-render";
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* 编辑按钮隐藏
|
|
27
|
+
*/
|
|
28
|
+
const editModeHideList = ["cell", "line-cell", "table-line-show"];
|
|
29
|
+
|
|
25
30
|
const TableRender = forwardRef(function (props, tableRef) {
|
|
26
|
-
const { topProps, config = {}, query = {}, i18n, setList } = props;
|
|
31
|
+
const { topProps, config = {}, query = {}, i18n, setList, schema } = props;
|
|
32
|
+
const propsSchema = schema?.schema;
|
|
27
33
|
const { tableDel = "删除", tableEdit = "编辑", tableDelTip = "确认删除该项?", tableDetail = "详情" } = i18n || {};
|
|
28
34
|
const {
|
|
29
35
|
dragColConf = {},
|
|
30
36
|
isDargTable,
|
|
31
37
|
dargEndBack,
|
|
32
|
-
orderColType,
|
|
38
|
+
orderColType = "page",
|
|
33
39
|
orderColWidth,
|
|
34
40
|
tableEmptyValue,
|
|
35
41
|
isShowTableFilter = false,
|
|
36
42
|
isTableSortXIdex = false,
|
|
37
43
|
} = config || {};
|
|
38
|
-
const
|
|
39
|
-
const
|
|
44
|
+
const [_list, _setList] = useState(props.list);
|
|
45
|
+
const antdTableRef = useRef();
|
|
46
|
+
const rowFormMapRef = useRef(new Map());
|
|
47
|
+
const editingInofRef = useRef({
|
|
48
|
+
editingRowId: "",
|
|
49
|
+
editingKey: "",
|
|
50
|
+
});
|
|
51
|
+
|
|
40
52
|
useImperativeHandle(tableRef, () => ({
|
|
41
53
|
onEditByTable,
|
|
42
54
|
}));
|
|
43
55
|
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
_setList(props.list);
|
|
58
|
+
// 数据清除问题,避免分页数据量持续累计过于庞大
|
|
59
|
+
rowFormMapRef.current.clear();
|
|
60
|
+
}, [props.list]);
|
|
61
|
+
|
|
44
62
|
const [columns, setColumns] = useState([]);
|
|
45
63
|
const [columnList, setColumnList] = useState([]);
|
|
46
64
|
const DragHandle = SortableHandle(() => <MenuOutlined style={{ cursor: "grab", color: "#999" }} />);
|
|
47
65
|
|
|
48
|
-
const SortableItem = SortableElement((props) => <
|
|
66
|
+
const SortableItem = SortableElement((props) => <Fragment children={props.children} />);
|
|
49
67
|
const SortableBody = SortableContainer((props) => <tbody {...props} />);
|
|
50
68
|
|
|
51
69
|
const onSortEnd = ({ oldIndex, newIndex }) => {
|
|
52
70
|
if (oldIndex !== newIndex) {
|
|
53
71
|
const newData = arrayMoveImmutable(props.list.slice(), oldIndex, newIndex).filter((el) => !!el);
|
|
54
72
|
setList([...newData]);
|
|
73
|
+
_setList([...newData]);
|
|
55
74
|
dargEndBack && dargEndBack(newData, query);
|
|
56
75
|
}
|
|
57
76
|
};
|
|
@@ -71,38 +90,27 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
71
90
|
fieldSchemas: {},
|
|
72
91
|
});
|
|
73
92
|
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
readOnly: props.readOnly,
|
|
80
|
-
disabled: props.disabled,
|
|
81
|
-
...(props.formOptions || {}),
|
|
82
|
-
effects(...args) {
|
|
83
|
-
props.onFormValuesChange && onFormValuesChange(props.onFormValuesChange);
|
|
84
|
-
props.onFieldValueChange && onFieldValueChange("*", props.onFieldValueChange);
|
|
85
|
-
props.formOptions?.effects && props.formOptions?.effects(...args);
|
|
86
|
-
},
|
|
87
|
-
}),
|
|
88
|
-
[],
|
|
89
|
-
);
|
|
90
|
-
const { onEdit: onEditByTable, mergedColumns } = useEditTable({
|
|
93
|
+
const {
|
|
94
|
+
onEditSave,
|
|
95
|
+
onEdit: onEditByTable,
|
|
96
|
+
mergedColumns,
|
|
97
|
+
} = useEditTable({
|
|
91
98
|
idKey: props.idKey,
|
|
92
99
|
columns,
|
|
93
100
|
onEdit: props.onEdit,
|
|
94
101
|
onEditSubmit: props.onEditSubmit,
|
|
95
|
-
formRender,
|
|
96
102
|
components: props.components,
|
|
97
103
|
schemaScope: props.schemaScope,
|
|
98
104
|
topProps: props.topProps,
|
|
105
|
+
rowFormMapRef,
|
|
106
|
+
editingInofRef,
|
|
99
107
|
});
|
|
100
108
|
|
|
101
109
|
useEffect(() => {
|
|
102
|
-
if (!
|
|
110
|
+
if (!propsSchema.properties) {
|
|
103
111
|
return;
|
|
104
112
|
}
|
|
105
|
-
const fieldList = getFieldList(
|
|
113
|
+
const fieldList = getFieldList(propsSchema, [], { ...props.getFieldListOpt, formilyRef }, isTableSortXIdex);
|
|
106
114
|
const columns = [];
|
|
107
115
|
|
|
108
116
|
// 序号列
|
|
@@ -131,10 +139,28 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
131
139
|
});
|
|
132
140
|
_fieldList.forEach((field, colIndex) => {
|
|
133
141
|
const fieldSchemas = formilyRef.current?.fields;
|
|
142
|
+
if (!field["x-decorator-props"]) {
|
|
143
|
+
field["x-decorator-props"] = {};
|
|
144
|
+
}
|
|
145
|
+
// 存储原始的 pattern,用于行内编辑还原数据
|
|
146
|
+
field["x-decorator-props"]._sourcePattern = field["x-pattern"];
|
|
134
147
|
if (field.inTable !== false) {
|
|
135
148
|
const { name, title } = field;
|
|
136
149
|
const comName = field["x-component"];
|
|
137
150
|
|
|
151
|
+
const decoratorProps = field["x-decorator-props"] || {};
|
|
152
|
+
let _title = title;
|
|
153
|
+
if (decoratorProps.tooltip) {
|
|
154
|
+
_title = (
|
|
155
|
+
<span className="col-title-tooltip-wrap inline-block-max-w">
|
|
156
|
+
{_title}
|
|
157
|
+
<Tooltip className="col-title-tooltip" title={decoratorProps.tooltip}>
|
|
158
|
+
<QuestionCircleOutlined className="col-title-tooltip-icon" />
|
|
159
|
+
</Tooltip>
|
|
160
|
+
</span>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
138
164
|
let _colConf = {};
|
|
139
165
|
|
|
140
166
|
if (props.config?.colConf && props.config?.colConf[name]) {
|
|
@@ -204,22 +230,6 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
204
230
|
};
|
|
205
231
|
}
|
|
206
232
|
|
|
207
|
-
let _title = isFunction(title) ? title() : title;
|
|
208
|
-
if (_colConf?.title) {
|
|
209
|
-
_title = isFunction(_colConf?.title) ? _colConf?.title() : _colConf?.title;
|
|
210
|
-
}
|
|
211
|
-
const decoratorProps = field["x-decorator-props"] || {};
|
|
212
|
-
if (decoratorProps.tooltip) {
|
|
213
|
-
_title = (
|
|
214
|
-
<span className="col-title-tooltip-wrap inline-block-max-w">
|
|
215
|
-
{_title}
|
|
216
|
-
<Tooltip className="col-title-tooltip" title={decoratorProps.tooltip}>
|
|
217
|
-
<QuestionCircleOutlined className="col-title-tooltip-icon" />
|
|
218
|
-
</Tooltip>
|
|
219
|
-
</span>
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
233
|
columns.push({
|
|
224
234
|
// field, // HACK: 直接传入 field 在 title 传入 ReactNode,内部深克隆导致页面报错白屏。使用函数获取解决
|
|
225
235
|
getField: () => field,
|
|
@@ -227,8 +237,8 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
227
237
|
..._colConf,
|
|
228
238
|
onCell: (record, rowIndex) =>
|
|
229
239
|
_colConf?.onCell?.({ ...record, _field: { ...field, ...(fieldSchemas?.[name] || {}) } }, rowIndex) || {},
|
|
230
|
-
// 函数式传入,解决 title ReactNode
|
|
231
|
-
title: () => _title,
|
|
240
|
+
// 函数式传入,解决 title ReactNode 传入报错问题
|
|
241
|
+
title: () => (isFunction(_colConf?.title) ? _colConf?.title() : _title),
|
|
232
242
|
key: name,
|
|
233
243
|
dataIndex: name,
|
|
234
244
|
render: getColRender(colRender),
|
|
@@ -256,8 +266,7 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
256
266
|
const { editMode = "modal" } = props.topProps || {};
|
|
257
267
|
// 编辑按钮权限
|
|
258
268
|
const _hasEdit =
|
|
259
|
-
editMode
|
|
260
|
-
editMode !== "line-cell" &&
|
|
269
|
+
!editModeHideList.includes(editMode) &&
|
|
261
270
|
(hasEdit && typeof hasEdit === "function" ? hasEdit(record, index) : hasEdit !== false);
|
|
262
271
|
|
|
263
272
|
//详情按钮权限
|
|
@@ -289,6 +298,10 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
289
298
|
type="link"
|
|
290
299
|
onClick={() => {
|
|
291
300
|
props.onEdit && props.onEdit(record, index);
|
|
301
|
+
if (editMode == "line") {
|
|
302
|
+
// 整行编辑,编辑按钮在操作列的模式下表单数据回填
|
|
303
|
+
return onEditByTable(record, record[props.idKey]);
|
|
304
|
+
}
|
|
292
305
|
}}
|
|
293
306
|
>
|
|
294
307
|
{tableEdit}
|
|
@@ -327,12 +340,7 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
327
340
|
}
|
|
328
341
|
setColumns(columns);
|
|
329
342
|
setColumnList(columns);
|
|
330
|
-
}, [
|
|
331
|
-
|
|
332
|
-
// 解决 FormilyField 中无相关参数报错的问题。自定义参数都从这里传入
|
|
333
|
-
const reactionOpts = {
|
|
334
|
-
scenario: scenario,
|
|
335
|
-
};
|
|
343
|
+
}, [propsSchema, props.config]);
|
|
336
344
|
|
|
337
345
|
const onChange = (e, col) => {
|
|
338
346
|
if (e.target.checked) {
|
|
@@ -346,38 +354,66 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
346
354
|
};
|
|
347
355
|
|
|
348
356
|
const tableProps = {
|
|
357
|
+
ref: antdTableRef,
|
|
349
358
|
className: "table-render",
|
|
350
359
|
rowKey: props.idKey || "id",
|
|
351
360
|
rowSelection: config?.rowSelection,
|
|
352
361
|
columns: columns,
|
|
353
|
-
dataSource:
|
|
362
|
+
dataSource: _list,
|
|
354
363
|
pagination: false,
|
|
355
364
|
scroll: config.scroll,
|
|
356
365
|
expandable: config.expandable,
|
|
357
366
|
loading: props.loading,
|
|
358
|
-
onRow:
|
|
367
|
+
onRow: (record, index) => {
|
|
368
|
+
const _onRowRes = config?.onRow && config?.onRow(record, index);
|
|
369
|
+
return {
|
|
370
|
+
..._onRowRes,
|
|
371
|
+
record,
|
|
372
|
+
id: record[props.idKey || "id"],
|
|
373
|
+
rowFormMapRef,
|
|
374
|
+
editingInofRef,
|
|
375
|
+
components: props.components,
|
|
376
|
+
topProps,
|
|
377
|
+
onEditSave,
|
|
378
|
+
};
|
|
379
|
+
},
|
|
359
380
|
topProps: props.topProps,
|
|
360
381
|
...props.tableProps,
|
|
361
382
|
};
|
|
362
383
|
|
|
363
|
-
|
|
364
|
-
tableProps.components = {
|
|
365
|
-
body: {
|
|
366
|
-
wrapper: DraggableContainer,
|
|
367
|
-
row: DraggableBodyRow,
|
|
368
|
-
},
|
|
369
|
-
};
|
|
370
|
-
}
|
|
384
|
+
tableProps.columns = mergedColumns;
|
|
371
385
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
386
|
+
// useMemo 解决 row 重复渲染问题
|
|
387
|
+
const tableComponents = useMemo(
|
|
388
|
+
() => ({
|
|
375
389
|
body: {
|
|
376
390
|
...tableProps?.components?.body,
|
|
377
391
|
cell: EditableCell,
|
|
392
|
+
row: isDargTable
|
|
393
|
+
? ({ rowFormMapRef, components, topProps, ...props }) => {
|
|
394
|
+
// 拖拽
|
|
395
|
+
return (
|
|
396
|
+
<DraggableBodyRow {...props}>
|
|
397
|
+
<EditTableRow rowFormMapRef={rowFormMapRef} components={components} topProps={topProps} {...props} />
|
|
398
|
+
</DraggableBodyRow>
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
: EditTableRow,
|
|
402
|
+
...(isDargTable
|
|
403
|
+
? {
|
|
404
|
+
wrapper: DraggableContainer,
|
|
405
|
+
}
|
|
406
|
+
: {}),
|
|
378
407
|
},
|
|
379
|
-
}
|
|
380
|
-
|
|
408
|
+
}),
|
|
409
|
+
[],
|
|
410
|
+
);
|
|
411
|
+
tableProps.components = tableComponents;
|
|
412
|
+
|
|
413
|
+
// 解决 FormilyField 中无相关参数报错的问题。自定义参数都从这里传入
|
|
414
|
+
const reactionOpts = {
|
|
415
|
+
scenario: scenario,
|
|
416
|
+
};
|
|
381
417
|
|
|
382
418
|
return (
|
|
383
419
|
<div className="table-render-wrap">
|
|
@@ -421,26 +457,24 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
421
457
|
</Popover>
|
|
422
458
|
</div>
|
|
423
459
|
) : null}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
) : (
|
|
460
|
+
<TableFormilyContext.Provider
|
|
461
|
+
value={{
|
|
462
|
+
rowFormMapRef,
|
|
463
|
+
editingInofRef,
|
|
464
|
+
}}
|
|
465
|
+
>
|
|
431
466
|
<Table {...tableProps} />
|
|
432
|
-
|
|
433
|
-
<FormilyField
|
|
434
|
-
schema={
|
|
467
|
+
</TableFormilyContext.Provider>
|
|
468
|
+
{/* <FormilyField
|
|
469
|
+
schema={propsSchema}
|
|
435
470
|
formilyRef={formilyRef}
|
|
436
471
|
components={props.components}
|
|
437
|
-
topProps={topProps}
|
|
438
472
|
schemaScope={{
|
|
439
473
|
...reactionOpts,
|
|
440
474
|
...props.schemaScope,
|
|
441
475
|
}}
|
|
442
476
|
reactionOpts={reactionOpts}
|
|
443
|
-
/>
|
|
477
|
+
/> */}
|
|
444
478
|
</div>
|
|
445
479
|
);
|
|
446
480
|
});
|