@hzab/list-render 1.10.20 → 1.10.21-alpha.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.
package/README.md
CHANGED
|
@@ -282,6 +282,26 @@ const Slots = {
|
|
|
282
282
|
| onEdit | row | 手动触发编辑按钮相关操作 |
|
|
283
283
|
| onDel | row | 手动触发删除按钮相关操作 |
|
|
284
284
|
|
|
285
|
+
#### cellEditTableProps
|
|
286
|
+
|
|
287
|
+
| 属性名称 | 属性类型 | 必须 | 默认值 | 描述 |
|
|
288
|
+
| -------------- | -------- | ---- | ------ | ------------------ |
|
|
289
|
+
| reactGridProps | Object | 否 | | reactGrid 相关参数 |
|
|
290
|
+
| onChange | Function | 否 | | 单元格回调 |
|
|
291
|
+
| formulaConfig | Object | 否 | | 运算相关配置 |
|
|
292
|
+
| headerHeight | number | 否 | | 表头高度 |
|
|
293
|
+
|
|
294
|
+
#### reactGridProps
|
|
295
|
+
|
|
296
|
+
| 属性名称 | 属性类型 | 必须 | 默认值 | 描述 |
|
|
297
|
+
| enableFillHandle | boolean | false | 开启后,选中单元格右下角会出现小方块,可拖拽快速复制 / 序列填充数据(类似 Excel 拖拽填充)|
|
|
298
|
+
| enableRangeSelection | boolean | false | 开启框选单元格区域(批量选中、批量编辑 / 填充必备)|
|
|
299
|
+
| onFocusLocationChanging | (location: CellLocation): boolean | 否 | 焦点 / 进入编辑态前回调,return false 阻止进入编辑)|
|
|
300
|
+
| customCellTemplates | Function | 否 | 注册自定义单元格模板(按钮、下拉、日期等单元格)|
|
|
301
|
+
| onSelectionChanged | Function | 否 | 选择区回调 |
|
|
302
|
+
| headerRowHeight | number | 否 | 表头高度 |
|
|
303
|
+
| rowHeight | number | 否 | 数据行高度 |
|
|
304
|
+
|
|
285
305
|
- onSearch opt
|
|
286
306
|
- isSaveQuery 是否保存传入的 query 值
|
|
287
307
|
- isMergeQuery 是否合并上一次保存的 query 值
|
|
@@ -568,6 +588,7 @@ async function test() {
|
|
|
568
588
|
## 命令
|
|
569
589
|
|
|
570
590
|
- Mac 执行该命令,设置 pre-commit 为可执行文件
|
|
591
|
+
|
|
571
592
|
- npm run mac-chmod
|
|
572
593
|
- chmod +x .husky && chmod +x .husky/pre-commit
|
|
573
594
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hzab/list-render",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.21-alpha.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "src",
|
|
6
6
|
"scripts": {
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"@hzab/formily-result-utils": "^1.2.0",
|
|
31
31
|
"@hzab/permissions": "^1.0.0",
|
|
32
32
|
"@hzab/schema-descriptions": "^1.3.0",
|
|
33
|
-
"@hzab/webpack-config": "^0.7.2",
|
|
34
33
|
"@hzab/utils": "^1.0.7",
|
|
34
|
+
"@hzab/webpack-config": "^0.7.2",
|
|
35
35
|
"@types/react": "^17.0.62",
|
|
36
36
|
"@types/react-dom": "^17.0.20",
|
|
37
37
|
"antd": "^4.24.12",
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"lib": "lib"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
+
"@silevis/reactgrid": "^4.1.17",
|
|
69
70
|
"array-move": "^4.0.0",
|
|
70
71
|
"react-sortable-hoc": "^2.0.0"
|
|
71
72
|
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { ReactGrid, Column, Row, CellChange, Cell, CellTemplate } from "@silevis/reactgrid";
|
|
3
|
+
import "@silevis/reactgrid/styles.css";
|
|
4
|
+
import _ from "lodash";
|
|
5
|
+
import "./index.less";
|
|
6
|
+
|
|
7
|
+
function isReactElement(value) {
|
|
8
|
+
return value !== null && typeof value === "object";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// 自定义单元格:状态标签(可编辑、带颜色)
|
|
12
|
+
export interface StatusCell extends Cell {
|
|
13
|
+
type: "status"; // 唯一标识,必须
|
|
14
|
+
text: string; // 状态文本(如:待办/进行中/完成)
|
|
15
|
+
color?: string; // 自定义颜色
|
|
16
|
+
validator?: (text: string) => boolean; // 可选:校验
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 合并所有单元格类型(供 rows 使用)
|
|
20
|
+
export type CustomCellTypes = StatusCell;
|
|
21
|
+
|
|
22
|
+
export default function CellEditTable(props: any) {
|
|
23
|
+
const {
|
|
24
|
+
columns,
|
|
25
|
+
dataSource,
|
|
26
|
+
formulaConfig,
|
|
27
|
+
onChange,
|
|
28
|
+
reactGridProps = {},
|
|
29
|
+
onEditSubmit,
|
|
30
|
+
headerRowHeight,
|
|
31
|
+
rowHeight,
|
|
32
|
+
} = props;
|
|
33
|
+
const [headerList, setHeaderList] = useState([]);
|
|
34
|
+
const [rows, setRows] = useState<any>([]);
|
|
35
|
+
const [tableColumns, setTableColumns] = useState([]);
|
|
36
|
+
|
|
37
|
+
/**将数组转为对象 */
|
|
38
|
+
const handleArrayToObj = (item) => {
|
|
39
|
+
let obj = {
|
|
40
|
+
id: item?.rowId,
|
|
41
|
+
};
|
|
42
|
+
item?.cells?.forEach((el) => {
|
|
43
|
+
if (el?.columnsId) {
|
|
44
|
+
obj[el?.columnsId] = el?.value || el?.selectedValue || el?.text || "";
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return obj;
|
|
48
|
+
};
|
|
49
|
+
/** 表头 */
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (Array.isArray(columns) && columns?.length > 0) {
|
|
52
|
+
const cells = columns?.map((item) => {
|
|
53
|
+
return {
|
|
54
|
+
type: "header",
|
|
55
|
+
text:
|
|
56
|
+
typeof item?.title == "function"
|
|
57
|
+
? isReactElement(item?.title())
|
|
58
|
+
? item?.title()?.props.children
|
|
59
|
+
: item?.title() || ""
|
|
60
|
+
: item?.title || "",
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
setHeaderList([
|
|
64
|
+
{
|
|
65
|
+
rowId: "header",
|
|
66
|
+
height: headerRowHeight,
|
|
67
|
+
cells: cells,
|
|
68
|
+
},
|
|
69
|
+
]);
|
|
70
|
+
setTableColumns(
|
|
71
|
+
columns?.map((item, index) => ({
|
|
72
|
+
...item,
|
|
73
|
+
columnId: item?.dataIndex || "",
|
|
74
|
+
})),
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
}, [columns]);
|
|
78
|
+
/** 数据行 */
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
const columnsIds = tableColumns?.map((el) => el?.columnId);
|
|
81
|
+
const newDataSource = dataSource?.map((item, index) => {
|
|
82
|
+
return {
|
|
83
|
+
rowId: item?.id,
|
|
84
|
+
height: rowHeight,
|
|
85
|
+
cells: columnsIds?.map((el, ind) => {
|
|
86
|
+
return {
|
|
87
|
+
type: tableColumns[ind]?.cellType ?? "text",
|
|
88
|
+
text: typeof item[el] == "string" ? item[el] : "",
|
|
89
|
+
columnsId: el,
|
|
90
|
+
nonEditable: !tableColumns[ind]?.editable,
|
|
91
|
+
...item,
|
|
92
|
+
};
|
|
93
|
+
}),
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
setRows([...headerList, ...newDataSource]);
|
|
97
|
+
}, [dataSource, tableColumns]);
|
|
98
|
+
|
|
99
|
+
// 单元格编辑回调
|
|
100
|
+
const handleCellsChanged = (changes) => {
|
|
101
|
+
setRows((prevRows) => {
|
|
102
|
+
changes.forEach((change) => {
|
|
103
|
+
const changeRowIdx = prevRows.findIndex((el) => el.rowId === change.rowId);
|
|
104
|
+
const changeColumnIdx = tableColumns.findIndex((el) => el.columnId === change.columnId);
|
|
105
|
+
prevRows[changeRowIdx].cells[changeColumnIdx] = change.newCell;
|
|
106
|
+
if (formulaConfig) {
|
|
107
|
+
for (let key in formulaConfig) {
|
|
108
|
+
const item = formulaConfig[key];
|
|
109
|
+
const resultColumnIdx = tableColumns.findIndex((el) => el.columnId === key);
|
|
110
|
+
const newCell = {
|
|
111
|
+
...prevRows[changeRowIdx].cells[resultColumnIdx],
|
|
112
|
+
text: item?.setCellData(prevRows[changeRowIdx]),
|
|
113
|
+
value: item?.setCellData(prevRows[changeRowIdx]),
|
|
114
|
+
style: item?.setCellStyle(item?.setCellData(prevRows[changeRowIdx])),
|
|
115
|
+
};
|
|
116
|
+
prevRows[changeRowIdx].cells[resultColumnIdx] = newCell;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
onEditSubmit && onEditSubmit(handleArrayToObj(prevRows[changeRowIdx]));
|
|
120
|
+
onChange && onChange(prevRows[changeRowIdx]);
|
|
121
|
+
});
|
|
122
|
+
return [...prevRows];
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<div className="grid-container">
|
|
128
|
+
<ReactGrid
|
|
129
|
+
rows={rows}
|
|
130
|
+
columns={tableColumns}
|
|
131
|
+
onCellsChanged={handleCellsChanged}
|
|
132
|
+
enableFillHandle={true}
|
|
133
|
+
enableRangeSelection={true}
|
|
134
|
+
stickyLeftColumns={1}
|
|
135
|
+
// customCellTemplates={{ status: StatusCellTemplate }}
|
|
136
|
+
// onFocusLocationChanging={(location) => {
|
|
137
|
+
// return false;
|
|
138
|
+
// }}
|
|
139
|
+
{...reactGridProps}
|
|
140
|
+
// onSelectionChanged={(newSelection) => {
|
|
141
|
+
// console.log("选区发生变化", newSelection[0]);
|
|
142
|
+
// }}
|
|
143
|
+
/>
|
|
144
|
+
</div>
|
|
145
|
+
);
|
|
146
|
+
}
|
package/src/list-render.jsx
CHANGED
|
@@ -17,13 +17,13 @@ import { getVal, getFieldList } from "../common/utils";
|
|
|
17
17
|
import { handleReactions } from "../common/handleReactions";
|
|
18
18
|
|
|
19
19
|
import { useEditTable, EditableCell } from "../components/Formily/FormilyEditTable";
|
|
20
|
-
|
|
20
|
+
import CellEditTable from "../components/CellEditTable"
|
|
21
21
|
import "./index.less";
|
|
22
22
|
|
|
23
23
|
const scenario = "table-render";
|
|
24
24
|
|
|
25
25
|
const TableRender = forwardRef(function (props, tableRef) {
|
|
26
|
-
const { topProps, config = {}, query = {}, i18n, setList } = props;
|
|
26
|
+
const { topProps, config = {}, query = {}, i18n, setList, cellEditTableProps } = props;
|
|
27
27
|
const { tableDel = "删除", tableEdit = "编辑", tableDelTip = "确认删除该项?", tableDetail = "详情" } = i18n || {};
|
|
28
28
|
const {
|
|
29
29
|
dragColConf = {},
|
|
@@ -34,6 +34,7 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
34
34
|
tableEmptyValue,
|
|
35
35
|
isShowTableFilter = false,
|
|
36
36
|
isTableSortXIdex = false,
|
|
37
|
+
isCellEditTable = false
|
|
37
38
|
} = config || {};
|
|
38
39
|
const { editMode = "modal" } = topProps || {};
|
|
39
40
|
const isEditTable = editMode !== "modal";
|
|
@@ -129,6 +130,7 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
129
130
|
scope: props.schemaScope,
|
|
130
131
|
formilyRef,
|
|
131
132
|
});
|
|
133
|
+
|
|
132
134
|
_fieldList.forEach((field, colIndex) => {
|
|
133
135
|
const fieldSchemas = formilyRef.current?.fields;
|
|
134
136
|
if (field.inTable !== false) {
|
|
@@ -231,6 +233,7 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
231
233
|
title: () => _title,
|
|
232
234
|
key: name,
|
|
233
235
|
dataIndex: name,
|
|
236
|
+
cellType: field?.cellType,
|
|
234
237
|
render: getColRender(colRender),
|
|
235
238
|
});
|
|
236
239
|
}
|
|
@@ -421,15 +424,23 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
421
424
|
</Popover>
|
|
422
425
|
</div>
|
|
423
426
|
) : null}
|
|
424
|
-
{
|
|
425
|
-
<
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
427
|
+
{
|
|
428
|
+
isCellEditTable ? <CellEditTable
|
|
429
|
+
{...tableProps}
|
|
430
|
+
{...cellEditTableProps}
|
|
431
|
+
onEditSubmit={props?.onEditSubmit}
|
|
432
|
+
/> : <>
|
|
433
|
+
{isEditTable ? (
|
|
434
|
+
<FormProvider form={formRender}>
|
|
435
|
+
<Form layout="vertical">
|
|
436
|
+
<FormConsumer>{() => <Table {...tableProps} />}</FormConsumer>
|
|
437
|
+
</Form>
|
|
438
|
+
</FormProvider>
|
|
439
|
+
) : (
|
|
440
|
+
<Table {...tableProps} />
|
|
441
|
+
)}
|
|
442
|
+
</>
|
|
443
|
+
}
|
|
433
444
|
<FormilyField
|
|
434
445
|
schema={props.schema}
|
|
435
446
|
formilyRef={formilyRef}
|