@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.
- package/CHANGELOG.md +9 -1
- package/README.md +0 -20
- package/package.json +4 -3
- package/src/DetailModal/index.jsx +120 -120
- package/src/FormModal/index.tsx +210 -210
- package/src/table-render/index.jsx +123 -119
- package/src/components/CellEditTable/Template/ExpandListTemplate/index.less +0 -18
- package/src/components/CellEditTable/Template/ExpandListTemplate/index.tsx +0 -92
- package/src/components/CellEditTable/Template/NumberCellTemplate.tsx +0 -168
- package/src/components/CellEditTable/Template/SelectCellTemplate.tsx +0 -202
- package/src/components/CellEditTable/Template/TextCellTemplate.tsx +0 -123
- package/src/components/CellEditTable/Template/utils.ts +0 -257
- package/src/components/CellEditTable/Template/widthWrap.tsx +0 -263
- package/src/components/CellEditTable/index.less +0 -11
- package/src/components/CellEditTable/index.tsx +0 -344
package/src/FormModal/index.tsx
CHANGED
|
@@ -1,210 +1,210 @@
|
|
|
1
|
-
import { forwardRef, useEffect, useImperativeHandle, useRef, useState, useMemo } from "react";
|
|
2
|
-
import _ from "lodash";
|
|
3
|
-
|
|
4
|
-
import { Modal, Drawer, Button, message } from "antd";
|
|
5
|
-
|
|
6
|
-
import FormRender from "@hzab/form-render";
|
|
7
|
-
|
|
8
|
-
import "./index.less";
|
|
9
|
-
|
|
10
|
-
let _formData = null;
|
|
11
|
-
|
|
12
|
-
export interface IFormRender {
|
|
13
|
-
setValues: Function;
|
|
14
|
-
reset: Function;
|
|
15
|
-
validate: Function;
|
|
16
|
-
values: Object;
|
|
17
|
-
}
|
|
18
|
-
export interface IFormRef {
|
|
19
|
-
formRender: IFormRender;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* 表单弹层,包含弹窗、抽屉两种模式
|
|
24
|
-
* @param props
|
|
25
|
-
* @param parentRef
|
|
26
|
-
* @returns
|
|
27
|
-
*/
|
|
28
|
-
export function FormModal(props, parentRef) {
|
|
29
|
-
const { modalMode, Slots = {}, modalConf = {}, modalProps = {} } = props;
|
|
30
|
-
const [loading, setLoading] = useState(false);
|
|
31
|
-
const [title, setTitle] = useState("新增");
|
|
32
|
-
const [open, setOpen] = useState(false);
|
|
33
|
-
const formRef = useRef<IFormRef>();
|
|
34
|
-
const scenarioRef = useRef<string>("create");
|
|
35
|
-
|
|
36
|
-
const FormSlot = useMemo(() => props.Slots?.FormSlot, [props.Slots?.FormSlot]);
|
|
37
|
-
|
|
38
|
-
function show(formData = props.formInitialValues, title, scenario = "create") {
|
|
39
|
-
scenarioRef.current = scenario || "create";
|
|
40
|
-
setOpen(true);
|
|
41
|
-
// 处理 formRef.current 为 undefined 的问题
|
|
42
|
-
if (formRef.current?.formRender?.setValues) {
|
|
43
|
-
formRef.current?.formRender?.setValues(formData);
|
|
44
|
-
_formData = null;
|
|
45
|
-
} else {
|
|
46
|
-
_formData = formData;
|
|
47
|
-
}
|
|
48
|
-
setTitle(title || "新增");
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function close() {
|
|
52
|
-
props.onClose && props.onClose();
|
|
53
|
-
setOpen(false);
|
|
54
|
-
formRef.current?.formRender?.reset();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
useImperativeHandle(parentRef, () => ({
|
|
58
|
-
show,
|
|
59
|
-
close,
|
|
60
|
-
cancel: close,
|
|
61
|
-
onOk,
|
|
62
|
-
formRef,
|
|
63
|
-
}));
|
|
64
|
-
|
|
65
|
-
// Hack: 解决 FormModal DetailModal 相互影响的问题
|
|
66
|
-
if (!open) {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function onOk() {
|
|
71
|
-
validate().then(async () => {
|
|
72
|
-
const submitForm = _.cloneDeep(await formRef.current?.formRender?.values);
|
|
73
|
-
if (modalConf.beforeSubmit) {
|
|
74
|
-
const isContinue = await modalConf.beforeSubmit(submitForm, {
|
|
75
|
-
cancel: close,
|
|
76
|
-
formRef,
|
|
77
|
-
scenario: scenarioRef.current,
|
|
78
|
-
});
|
|
79
|
-
if (isContinue === false) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
try {
|
|
85
|
-
setLoading(true);
|
|
86
|
-
await (props.onSubmit && props.onSubmit(submitForm));
|
|
87
|
-
close();
|
|
88
|
-
} catch (error) {
|
|
89
|
-
console.error(error);
|
|
90
|
-
}
|
|
91
|
-
setLoading(false);
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* 校验表单
|
|
97
|
-
* @returns
|
|
98
|
-
*/
|
|
99
|
-
function validate(hideMessage = false) {
|
|
100
|
-
return new Promise((resolve, reject) => {
|
|
101
|
-
formRef.current?.formRender
|
|
102
|
-
?.validate()
|
|
103
|
-
.then((values) => {
|
|
104
|
-
resolve(values);
|
|
105
|
-
})
|
|
106
|
-
.catch((err) => {
|
|
107
|
-
reject(err);
|
|
108
|
-
console.error("Error validate: ", err);
|
|
109
|
-
!hideMessage && message.error("输入有误!");
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
let footer = undefined;
|
|
115
|
-
const options = {
|
|
116
|
-
cancel: close,
|
|
117
|
-
onOk,
|
|
118
|
-
close,
|
|
119
|
-
formRef,
|
|
120
|
-
validate,
|
|
121
|
-
scenario: scenarioRef.current,
|
|
122
|
-
};
|
|
123
|
-
if (modalConf?.footer) {
|
|
124
|
-
footer = typeof modalConf?.footer === "function" ? modalConf.footer({ ...options, options }) : modalConf?.footer;
|
|
125
|
-
} else {
|
|
126
|
-
footer = [];
|
|
127
|
-
|
|
128
|
-
if (Slots.modalFooterPre) {
|
|
129
|
-
footer.push(<Slots.modalFooterPre key="pre" options={options} />);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
footer.push(
|
|
133
|
-
<Button key="cancel" onClick={close}>
|
|
134
|
-
{modalConf.cancelText || "取 消"}
|
|
135
|
-
</Button>,
|
|
136
|
-
);
|
|
137
|
-
|
|
138
|
-
if (Slots.modalFooterCenter) {
|
|
139
|
-
footer.push(<Slots.modalFooterCenter key="center" options={options} />);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
footer.push(
|
|
143
|
-
<Button key="confirm" type="primary" onClick={onOk} loading={loading}>
|
|
144
|
-
{modalConf.okText || "确 定"}
|
|
145
|
-
</Button>,
|
|
146
|
-
);
|
|
147
|
-
|
|
148
|
-
if (Slots.modalFooterSuffix) {
|
|
149
|
-
footer.push(<Slots.modalFooterSuffix key="suffix" options={options} />);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* 解决 show 函数中 formRef.current 为 undefined 的问题
|
|
155
|
-
*/
|
|
156
|
-
function didMount() {
|
|
157
|
-
props.modalFormMount && props.modalFormMount();
|
|
158
|
-
if (_formData) {
|
|
159
|
-
formRef.current?.formRender?.setValues(_formData);
|
|
160
|
-
_formData = null;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const CModal = modalMode === "drawer" ? Drawer : Modal;
|
|
165
|
-
const _modalProps = {
|
|
166
|
-
className: "form-modal",
|
|
167
|
-
wrapClassName: "form-modal",
|
|
168
|
-
title: title,
|
|
169
|
-
visible: open,
|
|
170
|
-
open: open,
|
|
171
|
-
onClose: close,
|
|
172
|
-
onCancel: close,
|
|
173
|
-
onOk: onOk,
|
|
174
|
-
footer: footer,
|
|
175
|
-
maskClosable: modalProps.maskClosable || false,
|
|
176
|
-
width: modalConf?.width ?? 720,
|
|
177
|
-
// 解决弹窗不销毁,表单远程数据没有更新的问题
|
|
178
|
-
destroyOnClose: true,
|
|
179
|
-
...modalProps,
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
return (
|
|
183
|
-
<CModal {..._modalProps}>
|
|
184
|
-
{FormSlot ? (
|
|
185
|
-
<FormSlot {...props} formRef={formRef} scenario={scenarioRef.current} schema={props.schema} />
|
|
186
|
-
) : (
|
|
187
|
-
<FormRender
|
|
188
|
-
{...props.formProps}
|
|
189
|
-
ref={formRef}
|
|
190
|
-
schema={props.schema}
|
|
191
|
-
schemaScope={{
|
|
192
|
-
scenario: scenarioRef.current,
|
|
193
|
-
...(props.schemaScope || {}),
|
|
194
|
-
}}
|
|
195
|
-
components={props.components}
|
|
196
|
-
></FormRender>
|
|
197
|
-
)}
|
|
198
|
-
<DidMount didMount={didMount} />
|
|
199
|
-
</CModal>
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
function DidMount(props) {
|
|
204
|
-
useEffect(() => {
|
|
205
|
-
props.didMount();
|
|
206
|
-
}, []);
|
|
207
|
-
return null;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
export default forwardRef(FormModal);
|
|
1
|
+
import { forwardRef, useEffect, useImperativeHandle, useRef, useState, useMemo } from "react";
|
|
2
|
+
import _ from "lodash";
|
|
3
|
+
|
|
4
|
+
import { Modal, Drawer, Button, message } from "antd";
|
|
5
|
+
|
|
6
|
+
import FormRender from "@hzab/form-render";
|
|
7
|
+
|
|
8
|
+
import "./index.less";
|
|
9
|
+
|
|
10
|
+
let _formData = null;
|
|
11
|
+
|
|
12
|
+
export interface IFormRender {
|
|
13
|
+
setValues: Function;
|
|
14
|
+
reset: Function;
|
|
15
|
+
validate: Function;
|
|
16
|
+
values: Object;
|
|
17
|
+
}
|
|
18
|
+
export interface IFormRef {
|
|
19
|
+
formRender: IFormRender;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 表单弹层,包含弹窗、抽屉两种模式
|
|
24
|
+
* @param props
|
|
25
|
+
* @param parentRef
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
28
|
+
export function FormModal(props, parentRef) {
|
|
29
|
+
const { modalMode, Slots = {}, modalConf = {}, modalProps = {} } = props;
|
|
30
|
+
const [loading, setLoading] = useState(false);
|
|
31
|
+
const [title, setTitle] = useState("新增");
|
|
32
|
+
const [open, setOpen] = useState(false);
|
|
33
|
+
const formRef = useRef<IFormRef>();
|
|
34
|
+
const scenarioRef = useRef<string>("create");
|
|
35
|
+
|
|
36
|
+
const FormSlot = useMemo(() => props.Slots?.FormSlot, [props.Slots?.FormSlot]);
|
|
37
|
+
|
|
38
|
+
function show(formData = props.formInitialValues, title, scenario = "create") {
|
|
39
|
+
scenarioRef.current = scenario || "create";
|
|
40
|
+
setOpen(true);
|
|
41
|
+
// 处理 formRef.current 为 undefined 的问题
|
|
42
|
+
if (formRef.current?.formRender?.setValues) {
|
|
43
|
+
formRef.current?.formRender?.setValues(formData);
|
|
44
|
+
_formData = null;
|
|
45
|
+
} else {
|
|
46
|
+
_formData = formData;
|
|
47
|
+
}
|
|
48
|
+
setTitle(title || "新增");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function close() {
|
|
52
|
+
props.onClose && props.onClose();
|
|
53
|
+
setOpen(false);
|
|
54
|
+
formRef.current?.formRender?.reset();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
useImperativeHandle(parentRef, () => ({
|
|
58
|
+
show,
|
|
59
|
+
close,
|
|
60
|
+
cancel: close,
|
|
61
|
+
onOk,
|
|
62
|
+
formRef,
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
// Hack: 解决 FormModal DetailModal 相互影响的问题
|
|
66
|
+
if (!open) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function onOk() {
|
|
71
|
+
validate().then(async () => {
|
|
72
|
+
const submitForm = _.cloneDeep(await formRef.current?.formRender?.values);
|
|
73
|
+
if (modalConf.beforeSubmit) {
|
|
74
|
+
const isContinue = await modalConf.beforeSubmit(submitForm, {
|
|
75
|
+
cancel: close,
|
|
76
|
+
formRef,
|
|
77
|
+
scenario: scenarioRef.current,
|
|
78
|
+
});
|
|
79
|
+
if (isContinue === false) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
setLoading(true);
|
|
86
|
+
await (props.onSubmit && props.onSubmit(submitForm));
|
|
87
|
+
close();
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error(error);
|
|
90
|
+
}
|
|
91
|
+
setLoading(false);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* 校验表单
|
|
97
|
+
* @returns
|
|
98
|
+
*/
|
|
99
|
+
function validate(hideMessage = false) {
|
|
100
|
+
return new Promise((resolve, reject) => {
|
|
101
|
+
formRef.current?.formRender
|
|
102
|
+
?.validate()
|
|
103
|
+
.then((values) => {
|
|
104
|
+
resolve(values);
|
|
105
|
+
})
|
|
106
|
+
.catch((err) => {
|
|
107
|
+
reject(err);
|
|
108
|
+
console.error("Error validate: ", err);
|
|
109
|
+
!hideMessage && message.error("输入有误!");
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let footer = undefined;
|
|
115
|
+
const options = {
|
|
116
|
+
cancel: close,
|
|
117
|
+
onOk,
|
|
118
|
+
close,
|
|
119
|
+
formRef,
|
|
120
|
+
validate,
|
|
121
|
+
scenario: scenarioRef.current,
|
|
122
|
+
};
|
|
123
|
+
if (modalConf?.footer) {
|
|
124
|
+
footer = typeof modalConf?.footer === "function" ? modalConf.footer({ ...options, options }) : modalConf?.footer;
|
|
125
|
+
} else {
|
|
126
|
+
footer = [];
|
|
127
|
+
|
|
128
|
+
if (Slots.modalFooterPre) {
|
|
129
|
+
footer.push(<Slots.modalFooterPre key="pre" options={options} />);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
footer.push(
|
|
133
|
+
<Button key="cancel" onClick={close}>
|
|
134
|
+
{modalConf.cancelText || "取 消"}
|
|
135
|
+
</Button>,
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
if (Slots.modalFooterCenter) {
|
|
139
|
+
footer.push(<Slots.modalFooterCenter key="center" options={options} />);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
footer.push(
|
|
143
|
+
<Button key="confirm" type="primary" onClick={onOk} loading={loading}>
|
|
144
|
+
{modalConf.okText || "确 定"}
|
|
145
|
+
</Button>,
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
if (Slots.modalFooterSuffix) {
|
|
149
|
+
footer.push(<Slots.modalFooterSuffix key="suffix" options={options} />);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* 解决 show 函数中 formRef.current 为 undefined 的问题
|
|
155
|
+
*/
|
|
156
|
+
function didMount() {
|
|
157
|
+
props.modalFormMount && props.modalFormMount();
|
|
158
|
+
if (_formData) {
|
|
159
|
+
formRef.current?.formRender?.setValues(_formData);
|
|
160
|
+
_formData = null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const CModal = modalMode === "drawer" ? Drawer : Modal;
|
|
165
|
+
const _modalProps = {
|
|
166
|
+
className: "form-modal",
|
|
167
|
+
wrapClassName: "form-modal",
|
|
168
|
+
title: title,
|
|
169
|
+
visible: open,
|
|
170
|
+
open: open,
|
|
171
|
+
onClose: close,
|
|
172
|
+
onCancel: close,
|
|
173
|
+
onOk: onOk,
|
|
174
|
+
footer: footer,
|
|
175
|
+
maskClosable: modalProps.maskClosable || false,
|
|
176
|
+
width: modalConf?.width ?? 720,
|
|
177
|
+
// 解决弹窗不销毁,表单远程数据没有更新的问题
|
|
178
|
+
destroyOnClose: true,
|
|
179
|
+
...modalProps,
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<CModal {..._modalProps}>
|
|
184
|
+
{FormSlot ? (
|
|
185
|
+
<FormSlot {...props} formRef={formRef} scenario={scenarioRef.current} schema={props.schema} />
|
|
186
|
+
) : (
|
|
187
|
+
<FormRender
|
|
188
|
+
{...props.formProps}
|
|
189
|
+
ref={formRef}
|
|
190
|
+
schema={props.schema}
|
|
191
|
+
schemaScope={{
|
|
192
|
+
scenario: scenarioRef.current,
|
|
193
|
+
...(props.schemaScope || {}),
|
|
194
|
+
}}
|
|
195
|
+
components={props.components}
|
|
196
|
+
></FormRender>
|
|
197
|
+
)}
|
|
198
|
+
<DidMount didMount={didMount} />
|
|
199
|
+
</CModal>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function DidMount(props) {
|
|
204
|
+
useEffect(() => {
|
|
205
|
+
props.didMount();
|
|
206
|
+
}, []);
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export default forwardRef(FormModal);
|
|
@@ -17,7 +17,7 @@ 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
|
-
import CellEditTable from "
|
|
20
|
+
import CellEditTable from "@hzab/edit-table"
|
|
21
21
|
import "./index.less";
|
|
22
22
|
|
|
23
23
|
const scenario = "table-render";
|
|
@@ -99,12 +99,131 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
99
99
|
topProps: props.topProps,
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
+
/** 处理childrn */
|
|
103
|
+
const handleChildColumns = (childColumns) => {
|
|
104
|
+
const fieldSchemas = formilyRef.current?.fields;
|
|
105
|
+
const { Slots = {} } = props;
|
|
106
|
+
return childColumns?.map((field, colIndex) => {
|
|
107
|
+
if (!(field.inTable !== false)) return
|
|
108
|
+
|
|
109
|
+
const { name, title } = field;
|
|
110
|
+
const comName = field["x-component"];
|
|
111
|
+
let _colConf = {};
|
|
112
|
+
if (props.config?.colConf && props.config?.colConf[field?.name]) {
|
|
113
|
+
_colConf = props.config?.colConf[field?.name];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let colRender = undefined;
|
|
117
|
+
if (Slots && Slots[field?.name]) {
|
|
118
|
+
colRender = function (text, record, index) {
|
|
119
|
+
const Slot = Slots[field?.name];
|
|
120
|
+
const slotProps = {
|
|
121
|
+
text,
|
|
122
|
+
record,
|
|
123
|
+
index,
|
|
124
|
+
field: { ...field, ...fieldSchemas?.[field?.name] },
|
|
125
|
+
fieldSchema: fieldSchemas?.[field?.name],
|
|
126
|
+
};
|
|
127
|
+
return <Slot {...slotProps} />;
|
|
128
|
+
};
|
|
129
|
+
} else {
|
|
130
|
+
colRender = function (text, record, index, ...args) {
|
|
131
|
+
const { width, ellipsis, emptyValue, showTags, showPrefixNode, showMode, enumRenderProps } = _colConf || {};
|
|
132
|
+
const schemaDefaultValue = fieldSchemas[field?.name]?.componentProps?.emptyValue;
|
|
133
|
+
const defaultValue = emptyValue ?? schemaDefaultValue ?? tableEmptyValue ?? "";
|
|
134
|
+
|
|
135
|
+
let val = getVal({ ...field, ...fieldSchemas[field?.name] }, record, {
|
|
136
|
+
fieldSchema: fieldSchemas?.[field?.name],
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
if (val === "" || val === undefined || val === null) {
|
|
140
|
+
val = defaultValue;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const content = (
|
|
144
|
+
<span className="inline-block-max-w" style={{ width }} title={ellipsis?.showTitle ? val : ""}>
|
|
145
|
+
{val}
|
|
146
|
+
</span>
|
|
147
|
+
);
|
|
148
|
+
if (ellipsis === true || (ellipsis && ellipsis?.showTitle != true)) {
|
|
149
|
+
return (
|
|
150
|
+
<Tooltip className="table-cell-ellipsis" {...ellipsis} title={val}>
|
|
151
|
+
{content}
|
|
152
|
+
</Tooltip>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (showMode || showTags || showPrefixNode || (showPrefixNode !== false && comName === "Switch")) {
|
|
157
|
+
// field 通过 fieldSchemas 获取最新的 field 数据
|
|
158
|
+
let _showMode = showMode;
|
|
159
|
+
if (showTags) {
|
|
160
|
+
_showMode = SHOW_MODE_TYPES.tags;
|
|
161
|
+
} else if (showPrefixNode) {
|
|
162
|
+
_showMode = SHOW_MODE_TYPES.prefixNode;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<EnumRender
|
|
167
|
+
showMode={_showMode}
|
|
168
|
+
value={_.get(record, field?.name)}
|
|
169
|
+
field={{ ...field, ...fieldSchemas?.[field?.name] }}
|
|
170
|
+
{...enumRenderProps}
|
|
171
|
+
/>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return content;
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
let _title = isFunction(title) ? title() : title;
|
|
181
|
+
if (_colConf?.title) {
|
|
182
|
+
_title = isFunction(_colConf?.title) ? _colConf?.title() : _colConf?.title;
|
|
183
|
+
}
|
|
184
|
+
const decoratorProps = field["x-decorator-props"] || {};
|
|
185
|
+
if (decoratorProps.tooltip) {
|
|
186
|
+
_title = (
|
|
187
|
+
<span className="col-title-tooltip-wrap inline-block-max-w">
|
|
188
|
+
{_title}
|
|
189
|
+
<Tooltip className="col-title-tooltip" title={decoratorProps.tooltip}>
|
|
190
|
+
<QuestionCircleOutlined className="col-title-tooltip-icon" />
|
|
191
|
+
</Tooltip>
|
|
192
|
+
</span>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
const childSelectList = fieldSchemas?.[field?.name]?.dataSource?.map((el) => ({
|
|
196
|
+
...el,
|
|
197
|
+
label: el?.[field?.["x-component-props"]?.["fieldNames"]?.["label"]] || el?.label,
|
|
198
|
+
value: el?.[field?.["x-component-props"]?.["fieldNames"]?.["value"]] || el?.value,
|
|
199
|
+
}))
|
|
200
|
+
return {
|
|
201
|
+
getField: () => field,
|
|
202
|
+
editable: true,
|
|
203
|
+
..._colConf,
|
|
204
|
+
onCell: (record, rowIndex, ci) =>
|
|
205
|
+
_colConf?.onCell?.({ ...record, _field: { ...field, ...(fieldSchemas?.[field?.name] || {}) } }, rowIndex, ci) || {},
|
|
206
|
+
// 函数式传入,解决 title ReactNode 传入报错问题(table 组件内部对 columns 进行 lodash.deepClone 导致 ReactNode 变成对象无法正常渲染) Uncaught TypeError: this.queryFeedbacks is not a function
|
|
207
|
+
title: () => _title,
|
|
208
|
+
key: field?.name,
|
|
209
|
+
dataIndex: field?.name,
|
|
210
|
+
type: field["x-validator"] == "number" ? "Number" : comName,
|
|
211
|
+
validatorList: field["x-validator"] || [],
|
|
212
|
+
nonEditable: editMode != "cell",
|
|
213
|
+
values: field?.enum || childSelectList || [],
|
|
214
|
+
cellProps: field.cellProps,
|
|
215
|
+
children: handleChildColumns(field?.children),
|
|
216
|
+
render: getColRender(colRender),
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
})?.filter((el) => (el))
|
|
220
|
+
}
|
|
102
221
|
useEffect(() => {
|
|
103
222
|
if (!(props.schema && props.schema.properties)) {
|
|
104
223
|
return;
|
|
105
224
|
}
|
|
106
225
|
const fieldList = getFieldList(props.schema, [], { ...props.getFieldListOpt, formilyRef }, isTableSortXIdex);
|
|
107
|
-
|
|
226
|
+
let columns = [];
|
|
108
227
|
|
|
109
228
|
// 序号列
|
|
110
229
|
if (orderColType === "page") {
|
|
@@ -130,123 +249,7 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
130
249
|
scope: props.schemaScope,
|
|
131
250
|
formilyRef,
|
|
132
251
|
});
|
|
133
|
-
|
|
134
|
-
_fieldList.forEach((field, colIndex) => {
|
|
135
|
-
const fieldSchemas = formilyRef.current?.fields;
|
|
136
|
-
if (field.inTable !== false) {
|
|
137
|
-
const { name, title } = field;
|
|
138
|
-
const comName = field["x-component"];
|
|
139
|
-
|
|
140
|
-
let _colConf = {};
|
|
141
|
-
|
|
142
|
-
if (props.config?.colConf && props.config?.colConf[name]) {
|
|
143
|
-
_colConf = props.config?.colConf[name];
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
let colRender = undefined;
|
|
147
|
-
if (Slots && Slots[name]) {
|
|
148
|
-
colRender = function (text, record, index) {
|
|
149
|
-
const Slot = Slots[name];
|
|
150
|
-
const slotProps = {
|
|
151
|
-
text,
|
|
152
|
-
record,
|
|
153
|
-
index,
|
|
154
|
-
field: { ...field, ...fieldSchemas?.[name] },
|
|
155
|
-
fieldSchema: fieldSchemas?.[name],
|
|
156
|
-
};
|
|
157
|
-
return <Slot {...slotProps} />;
|
|
158
|
-
};
|
|
159
|
-
} else {
|
|
160
|
-
colRender = function (text, record, index, ...args) {
|
|
161
|
-
const { width, ellipsis, emptyValue, showTags, showPrefixNode, showMode, enumRenderProps } = _colConf || {};
|
|
162
|
-
const schemaDefaultValue = fieldSchemas[name]?.componentProps?.emptyValue;
|
|
163
|
-
const defaultValue = emptyValue ?? schemaDefaultValue ?? tableEmptyValue ?? "";
|
|
164
|
-
|
|
165
|
-
let val = getVal({ ...field, ...fieldSchemas[name] }, record, {
|
|
166
|
-
fieldSchema: fieldSchemas?.[name],
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
if (val === "" || val === undefined || val === null) {
|
|
170
|
-
val = defaultValue;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const content = (
|
|
174
|
-
<span className="inline-block-max-w" style={{ width }} title={ellipsis?.showTitle ? val : ""}>
|
|
175
|
-
{val}
|
|
176
|
-
</span>
|
|
177
|
-
);
|
|
178
|
-
if (ellipsis === true || (ellipsis && ellipsis?.showTitle != true)) {
|
|
179
|
-
return (
|
|
180
|
-
<Tooltip className="table-cell-ellipsis" {...ellipsis} title={val}>
|
|
181
|
-
{content}
|
|
182
|
-
</Tooltip>
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (showMode || showTags || showPrefixNode || (showPrefixNode !== false && comName === "Switch")) {
|
|
187
|
-
// field 通过 fieldSchemas 获取最新的 field 数据
|
|
188
|
-
let _showMode = showMode;
|
|
189
|
-
if (showTags) {
|
|
190
|
-
_showMode = SHOW_MODE_TYPES.tags;
|
|
191
|
-
} else if (showPrefixNode) {
|
|
192
|
-
_showMode = SHOW_MODE_TYPES.prefixNode;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return (
|
|
196
|
-
<EnumRender
|
|
197
|
-
showMode={_showMode}
|
|
198
|
-
value={_.get(record, name)}
|
|
199
|
-
field={{ ...field, ...fieldSchemas?.[name] }}
|
|
200
|
-
{...enumRenderProps}
|
|
201
|
-
/>
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return content;
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
let _title = isFunction(title) ? title() : title;
|
|
210
|
-
if (_colConf?.title) {
|
|
211
|
-
_title = isFunction(_colConf?.title) ? _colConf?.title() : _colConf?.title;
|
|
212
|
-
}
|
|
213
|
-
const decoratorProps = field["x-decorator-props"] || {};
|
|
214
|
-
if (decoratorProps.tooltip) {
|
|
215
|
-
_title = (
|
|
216
|
-
<span className="col-title-tooltip-wrap inline-block-max-w">
|
|
217
|
-
{_title}
|
|
218
|
-
<Tooltip className="col-title-tooltip" title={decoratorProps.tooltip}>
|
|
219
|
-
<QuestionCircleOutlined className="col-title-tooltip-icon" />
|
|
220
|
-
</Tooltip>
|
|
221
|
-
</span>
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
const selectList = fieldSchemas?.[name]?.dataSource?.map((el) => ({
|
|
225
|
-
...el,
|
|
226
|
-
label: el?.[field?.["x-component-props"]?.["fieldNames"]?.["label"]] || el?.label,
|
|
227
|
-
value: el?.[field?.["x-component-props"]?.["fieldNames"]?.["value"]] || el?.value,
|
|
228
|
-
}))
|
|
229
|
-
|
|
230
|
-
columns.push({
|
|
231
|
-
// field, // HACK: 直接传入 field 在 title 传入 ReactNode,内部深克隆导致页面报错白屏。使用函数获取解决
|
|
232
|
-
getField: () => field,
|
|
233
|
-
editable: true,
|
|
234
|
-
..._colConf,
|
|
235
|
-
onCell: (record, rowIndex, ci) =>
|
|
236
|
-
_colConf?.onCell?.({ ...record, _field: { ...field, ...(fieldSchemas?.[name] || {}) } }, rowIndex, ci) || {},
|
|
237
|
-
// 函数式传入,解决 title ReactNode 传入报错问题(table 组件内部对 columns 进行 lodash.deepClone 导致 ReactNode 变成对象无法正常渲染) Uncaught TypeError: this.queryFeedbacks is not a function
|
|
238
|
-
title: () => _title,
|
|
239
|
-
key: name,
|
|
240
|
-
dataIndex: name,
|
|
241
|
-
type: field["x-validator"] == "number" ? "Number" : comName,
|
|
242
|
-
nonEditable: editMode != "cell",
|
|
243
|
-
values: field?.enum || selectList || [],
|
|
244
|
-
cellProps: field.cellProps,
|
|
245
|
-
children: field?.children,
|
|
246
|
-
render: getColRender(colRender),
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
});
|
|
252
|
+
columns = columns.concat(handleChildColumns(_fieldList))
|
|
250
253
|
|
|
251
254
|
if (props.hasAction !== false) {
|
|
252
255
|
const { hasEdit, hasDel, hasDelTips, hasDetail = false } = props.config || {};
|
|
@@ -439,6 +442,7 @@ const TableRender = forwardRef(function (props, tableRef) {
|
|
|
439
442
|
isCellEditTable ? <CellEditTable
|
|
440
443
|
{...tableProps}
|
|
441
444
|
{...cellEditTableProps}
|
|
445
|
+
{...props}
|
|
442
446
|
onEditSubmit={props?.onEditSubmit}
|
|
443
447
|
Slots={props?.Slots}
|
|
444
448
|
rowSelection={config?.rowSelection}
|