@hzab/list-render 1.11.0 → 1.12.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.
@@ -1,344 +0,0 @@
1
- import React, { memo, useEffect, useMemo, 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
- import { TextTemplate } from "./Template/TextCellTemplate";
7
- import { antdComponents, customComponents } from "@hzab/form-render/src/index";
8
- import { WidthWrap } from "./Template/widthWrap";
9
- import { NumberTemplate } from "./Template/NumberCellTemplate";
10
- import { Checkbox, Spin } from "antd";
11
- import { ExpandListTemplate } from "./Template/ExpandListTemplate";
12
- import { convertColumnsToRows, flattenColumns } from "./Template/utils";
13
-
14
- export default memo(function CellEditTable(props: any) {
15
- const {
16
- columns,
17
- dataSource,
18
- formulaConfig,
19
- onChange,
20
- reactGridProps = {},
21
- onEditSubmit,
22
- headerRowHeight,
23
- rowHeight,
24
- reactGridStyle,
25
- className,
26
- Slots,
27
- rowSelection,
28
- rowKey,
29
- query,
30
- loading,
31
- } = props;
32
-
33
- const [headerList, setHeaderList] = useState<any>([]);
34
- const [rows, setRows] = useState<any>([]);
35
- const [tableColumns, setTableColumns] = useState<any>([]);
36
- const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
37
- const [newDataSource, setNewDataSource] = useState<any>([]);
38
- const [expandKeys, setExpandKeys] = useState<any>([]);
39
- useEffect(() => {
40
- setNewDataSource(dataSource);
41
- }, [dataSource]);
42
- /**将数组转为对象 */
43
- const handleArrayToObj = (item) => {
44
- const record = item?.cells?.[0]?.record;
45
- const fieldList = ["_$actions", "rowSelection"];
46
- let obj: any = {
47
- id: item?.rowId,
48
- };
49
- item?.cells?.forEach((el) => {
50
- if (el?.columnId && !fieldList?.includes(el?.columnId)) {
51
- obj[el?.columnId] = el?.text || el?.value || el?.selectedValue || "";
52
- }
53
- });
54
-
55
- return {
56
- ...record,
57
- ...obj,
58
- };
59
- };
60
- /** 表头 */
61
- useEffect(() => {
62
- if (Array.isArray(columns) && columns?.length > 0) {
63
- if (rowSelection) {
64
- columns.unshift({
65
- type: "rowSelection",
66
- width: rowSelection?.width || 30,
67
- key: "rowSelection",
68
- style: rowSelection?.style || {
69
- background: "rgba(128, 128, 128, 0.1)",
70
- display: "flex",
71
- justifyContent: "center",
72
- },
73
- });
74
- }
75
- // const cells = columns?.map((item, index) => {
76
- // return {
77
- // type: item?.type == "rowSelection" ? "rowSelection" : "header",
78
- // text:
79
- // typeof item?.title == "function"
80
- // ? isReactElement(item?.title())
81
- // ? item?.title()?.props.children
82
- // : String(item?.title()) || ""
83
- // : String(item?.title) || "",
84
- // style: item?.type == "rowSelection" ? item?.style : {},
85
- // onCell: item?.onCell,
86
- // };
87
- // });
88
- setHeaderList(convertColumnsToRows(columns, headerRowHeight));
89
- const newColumns = flattenColumns(columns);
90
- setTableColumns(
91
- newColumns?.map((item, index) => ({
92
- ...item,
93
- columnId: item?.dataIndex || item?.key || "",
94
- })),
95
- );
96
- }
97
- }, [columns, rowSelection]);
98
-
99
- /** 数据行 */
100
- useEffect(() => {
101
- const columnsIds = tableColumns?.map((el) => el?.columnId);
102
- const tempDataSource = newDataSource?.map((item, index) => {
103
- return {
104
- rowId: item[rowKey],
105
- height: rowHeight,
106
- cells: columnsIds?.map((el, ind) => {
107
- let newCell = {};
108
- const columnsItem = tableColumns[ind];
109
- const cellItem = item[el];
110
- let type: any = columnsItem?.type ?? "text";
111
- if (!rowSelection && ind == 0) {
112
- type = "ExpandListTemplate";
113
- }
114
- if (rowSelection && ind == 1) {
115
- type = "ExpandListTemplate";
116
- }
117
-
118
- if (formulaConfig) {
119
- for (let key in formulaConfig) {
120
- if (key == el) {
121
- const it = formulaConfig[key];
122
- newCell = {
123
- text: it?.setCellData(item),
124
- value: it?.setCellData(item),
125
- style: it?.setCellStyle(it?.setCellData(item)),
126
- };
127
- }
128
- }
129
- }
130
-
131
- return {
132
- ...columnsItem,
133
- record: item,
134
- rowId: item[rowKey] || columnsItem?.type,
135
- type: type,
136
- nonEditable: columnsItem?.nonEditable,
137
- text: String(cellItem || ""),
138
- value: cellItem,
139
- selectedValue: cellItem || "",
140
- // rowspan: item?.extendedConfig?.name == el ? item?.extendedConfig?.rowspan || 0 : 0,
141
- // colspan: item?.extendedConfig?.name == el ? item?.extendedConfig?.colspan || 0 : 0,
142
- style: columnsItem?.type == "rowSelection" ? { display: "flex", justifyContent: "center" } : {},
143
- ...((columnsItem?.onCell && columnsItem?.onCell(item, index, ind)) || {}),
144
- ...(columnsItem?.cellProps || {}),
145
- setNewDataSource,
146
- setExpandKeys,
147
- rowKey,
148
- expandKeys,
149
- Slots,
150
- ...newCell,
151
-
152
- // style:item?.extendedConfig?.name==el?item?.extendedConfig?.style||{}:{}
153
- // ...handleType(item[el],tableColumns[ind]),
154
- };
155
- }),
156
- };
157
- });
158
- setRows(_.uniqBy([...headerList, ...tempDataSource], "rowId"));
159
- }, [newDataSource, tableColumns, rowSelection]);
160
-
161
- // 单元格编辑回调
162
- const handleCellsChanged = (changes) => {
163
- if (!Array.isArray(changes) || changes.length === 0) return;
164
- const hasDiff = changes.some((c) => JSON.stringify(c.previousCell) !== JSON.stringify(c.newCell));
165
- if (!hasDiff) return;
166
- setRows((prevRows) => {
167
- changes.forEach((change) => {
168
- const changeRowIdx = prevRows.findIndex((el) => el.rowId == change.rowId);
169
- const changeColumnIdx = tableColumns.findIndex((el) => el.columnId == change.columnId);
170
- prevRows[changeRowIdx].cells[changeColumnIdx] = change.newCell;
171
- if (formulaConfig) {
172
- for (let key in formulaConfig) {
173
- const item = formulaConfig[key];
174
- const resultColumnIdx = tableColumns.findIndex((el) => el.columnId == key);
175
- const newCell = {
176
- ...prevRows[changeRowIdx].cells[resultColumnIdx],
177
- text: item?.setCellData(prevRows[changeRowIdx]),
178
- value: item?.setCellData(prevRows[changeRowIdx]),
179
- style: item?.setCellStyle(item?.setCellData(prevRows[changeRowIdx])),
180
- };
181
- prevRows[changeRowIdx].cells[resultColumnIdx] = newCell;
182
- }
183
- }
184
- onEditSubmit && onEditSubmit(handleArrayToObj(prevRows[changeRowIdx]));
185
- onChange && onChange(prevRows[changeRowIdx]);
186
- });
187
- return [...prevRows];
188
- });
189
- };
190
-
191
- /**提取组件内部子组件 */
192
- function extractSubComponents(comp, compName): any {
193
- if (!comp || typeof comp !== "object") return {};
194
-
195
- return Object.entries(comp).reduce((result, [key, value]) => {
196
- // 匹配 antd 规范子组件命名:XXPicker / XX / 驼峰组件名
197
- // 排除普通函数、数字、布尔、内部私有属性(带下划线)、原型上的方法
198
- const isNativeFunc = ["render", "defaultProps", "propTypes", "displayName", "Group", "$$typeof"].includes(key);
199
- // 判定为子组件:值是函数(React组件本质是函数/类),且不是内部方法
200
- const isSubComponent = typeof comp == "object" && !isNativeFunc;
201
-
202
- if (isSubComponent) {
203
- result[`${compName}.${key}`] = value;
204
- }
205
- return result;
206
- }, {});
207
- }
208
- /** 自定义组件注册 */
209
- const baseTemplate = useMemo(() => {
210
- const mergeTemplate: any = { ...(antdComponents || {}), ...(customComponents || {}) };
211
- const newMergeTemplate: any = {};
212
- for (let key in mergeTemplate) {
213
- for (let it in extractSubComponents(mergeTemplate[key], key)) {
214
- newMergeTemplate[it] = WidthWrap({ WrapComponent: extractSubComponents(mergeTemplate[key], key)[it] });
215
- }
216
- newMergeTemplate[key] = WidthWrap({ WrapComponent: mergeTemplate[key] });
217
- }
218
- return newMergeTemplate;
219
- }, [antdComponents, customComponents]);
220
-
221
- const ActionDom = (props) => {
222
- return (
223
- <div onPointerDown={(e) => e.stopPropagation()}>
224
- {Slots?.tableActionsSlot && <Slots.tableActionsSlot {...props} />}
225
- {Slots?.actionPrefixSlot && <Slots.actionPrefixSlot {...props} />}
226
- {Slots?.actionCenterSlot && <Slots.actionCenterSlot {...props} />}
227
- {Slots?.actionSuffixSlot && <Slots.actionSuffixSlot {...props} />}
228
- </div>
229
- );
230
- };
231
-
232
- const CheckBoxDom = (props) => {
233
- return (
234
- <Checkbox
235
- {...props}
236
- checked={
237
- rowSelection?.selectedRowKeys?.includes((props?.record && props?.record[rowKey]) || "") ||
238
- (rowSelection?.selectedRowKeys?.length == dataSource?.length && dataSource?.length > 0)
239
- }
240
- indeterminate={
241
- !props?.rowId &&
242
- rowSelection?.selectedRowKeys?.length > 0 &&
243
- rowSelection?.selectedRowKeys?.length < dataSource?.length
244
- }
245
- onChange={(e) => {
246
- if (e.target.checked && props?.rowId) {
247
- const newSelectedRowKeys = [...rowSelection?.selectedRowKeys, props?.record[rowKey]];
248
- const rows = dataSource?.filter((el) => newSelectedRowKeys?.includes(el[rowKey]));
249
-
250
- rowSelection?.onChange(newSelectedRowKeys, rows);
251
- } else if (!e.target.checked && props?.rowId) {
252
- const newSelectedRowKeys = rowSelection?.selectedRowKeys?.filter((el) => el != props?.record[rowKey]);
253
- const rows = dataSource?.filter((el) => newSelectedRowKeys?.includes(el[rowKey]));
254
-
255
- rowSelection?.onChange(
256
- rowSelection?.selectedRowKeys?.filter((el) => el != props?.record[rowKey]),
257
- rows,
258
- );
259
- } else if (e.target.checked && !props?.rowId) {
260
- const newSelectedRowKeys = dataSource?.map((el) => el[rowKey]);
261
- const rows = dataSource?.filter((el) => newSelectedRowKeys?.includes(el[rowKey]));
262
-
263
- rowSelection?.onChange(
264
- dataSource?.map((el) => el[rowKey]),
265
- rows,
266
- );
267
- } else if (!e.target.checked && !props?.rowId) {
268
- rowSelection?.onChange([], []);
269
- }
270
- }}
271
- ></Checkbox>
272
- );
273
- };
274
- useEffect(() => {
275
- if (rowSelection) {
276
- const rows = dataSource?.filter((el) => selectedRowKeys?.includes(el[rowKey]));
277
- rowSelection?.onChange(selectedRowKeys, rows);
278
- }
279
- }, [selectedRowKeys, dataSource]);
280
- useEffect(() => {
281
- setSelectedRowKeys([]);
282
- }, [query?.pageNum]);
283
-
284
- return (
285
- <Spin spinning={loading}>
286
- <div className={`grid-container ${className}`} style={reactGridStyle}>
287
- <ReactGrid
288
- rows={rows}
289
- columns={tableColumns}
290
- onCellsChanged={handleCellsChanged}
291
- enableFillHandle={true}
292
- enableRangeSelection={true}
293
- horizontalStickyBreakpoint={120}
294
- // stickyLeftColumns={1}
295
- // onFocusLocationChanging={(location) => {
296
- // return false;
297
- // }}
298
- {...reactGridProps}
299
- onFocusLocationChanging={(cell: any) => {
300
- const datatypeId = cell?.columnId + cell?.rowId;
301
- window.gridEditId = datatypeId;
302
-
303
- if (["_$actions", "rowSelection"]?.includes(cell?.columnId)) {
304
- return false;
305
- }
306
-
307
- if (reactGridProps?.onFocusLocationChanging) {
308
- return reactGridProps?.onFocusLocationChanging(cell, rows);
309
- }
310
- return cell;
311
- }}
312
- customCellTemplates={{
313
- ...baseTemplate,
314
- ...reactGridProps?.customCellTemplates,
315
- _$actions: WidthWrap(
316
- {
317
- WrapComponent: ActionDom,
318
- },
319
- true,
320
- ),
321
- rowSelection: WidthWrap(
322
- {
323
- WrapComponent: CheckBoxDom,
324
- },
325
- true,
326
- ),
327
- Input: TextTemplate,
328
- Number: NumberTemplate,
329
- ExpandListTemplate: WidthWrap(
330
- {
331
- WrapComponent: ExpandListTemplate,
332
- },
333
- true,
334
- ),
335
- }}
336
-
337
- // onSelectionChanged={(newSelection) => {
338
- // console.log("选区发生变化", newSelection[0]);
339
- // }}
340
- />
341
- </div>
342
- </Spin>
343
- );
344
- });