@hzab/list-render 1.10.20-alpha.6 → 1.10.21-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.
@@ -1,272 +0,0 @@
1
- import { useEffect, useMemo, useRef, useState, forwardRef, useImperativeHandle } from "react";
2
- import { Button } from "antd";
3
- import { cloneDeep } from "lodash";
4
- import { Schema } from "@formily/json-schema";
5
-
6
- import FormRender from "@hzab/form-render";
7
- import { useIndex, useArray, useRecord, SortHandle } from "@hzab/form-render/src/components/ArrayBase";
8
-
9
- import SchemaToArrayTable from "../components/Formily/SchemaToArrayTable";
10
- import { useSlotsComponents } from "../components/Formily/useComponents";
11
- import TableActions from "../table-render/TableActions";
12
-
13
- import "./index.less";
14
-
15
- export interface IEditArrayTableProps {
16
- topProps: {
17
- editMode?: string;
18
- fetchOnEdit?: boolean;
19
- hasAction?: boolean;
20
- hideMessage?: boolean;
21
- Slots?: Object;
22
- };
23
- config?: {
24
- isDargTable?: boolean;
25
- orderColType?: string;
26
- colConf?: {
27
- _$actions: Object;
28
- };
29
- rowSelection: {
30
- selectedRowKeys: any[];
31
- };
32
- tableProps: {
33
- rowSelection: {
34
- selectedRowKeys: any[];
35
- };
36
- };
37
- };
38
- schema: Schema;
39
- list: Object[];
40
- components: Object[];
41
- schemaScope: Object;
42
- onDetail;
43
- onEdit;
44
- onEditByTable;
45
- onDel;
46
- onSearch;
47
- getList: () => Promise<{ list: any[] }>;
48
- onEditSubmit: (val) => void;
49
- handleMessage: (msg) => void;
50
- query: {
51
- pageNum: number;
52
- pageSize: number;
53
- };
54
- }
55
-
56
- // TODO: 权限、列显隐
57
- export const EditArrayTable = forwardRef(function (props: IEditArrayTableProps, parentRef) {
58
- const { topProps, schemaScope, getList, handleMessage, config, query } = props;
59
- const { hasAction, editMode } = topProps || {};
60
- const { orderColType, tableProps } = config || {};
61
-
62
- const [editing, setEditing] = useState(false);
63
- const [loading, setLoading] = useState(false);
64
- const formRef = useRef(null);
65
- const preValRef = useRef(null);
66
- const queryRef = useRef(props.query);
67
-
68
- queryRef.current = query;
69
-
70
- const schema = useMemo(() => {
71
- const schemaToArrayTable = new SchemaToArrayTable({
72
- schema: props.schema,
73
- config: { hasAction, hasIndex: orderColType === "page" || orderColType === "all", ...config },
74
- topProps,
75
- });
76
- return schemaToArrayTable.handleSchema();
77
- }, [props.schema]);
78
-
79
- const slotComponents = useSlotsComponents(topProps);
80
- const components = useMemo(() => {
81
- const coms = {
82
- TableIndex() {
83
- const index = useIndex();
84
- // 序号列
85
- if (orderColType === "page") {
86
- return index + 1;
87
- } else if (orderColType == "all") {
88
- const { pageSize = 10, pageNum = 1 } = queryRef.current || {};
89
- // 当前页数减1乘以每一页页数再加当前页序号+1
90
- return (pageNum - 1) * pageSize + (index + 1);
91
- }
92
- return null;
93
- },
94
- ...slotComponents,
95
- TableActions(tProps) {
96
- const index = useIndex();
97
- const array = useArray();
98
- const { onDetail, onEdit, onDel, onSearch, getList } = props;
99
- const record = useRecord();
100
- const cProps = {
101
- ...tProps,
102
- record,
103
- index,
104
- Slots: topProps.Slots,
105
- onEdit,
106
- onDel() {
107
- array.field?.remove?.(index);
108
- array.props?.onRemove?.(index);
109
- onDel && onDel(record, index);
110
- },
111
- onDetail,
112
- onSearch,
113
- // TODO: 编辑删除按钮状态
114
- // hasEdit,
115
- // hasDel,
116
- // onEditByTable,
117
- getList,
118
- tableConf: props.config,
119
- colConf: config?.colConf?._$actions,
120
- topProps,
121
- };
122
- return <TableActions {...cProps} />;
123
- },
124
- };
125
- // HACK: 解决只读无法拖拽的问题
126
- coms.ArrayTable.SortHandle = SortHandle;
127
- return coms;
128
- }, [slotComponents, props.query.pageNum, props.query.pageSize]);
129
-
130
- useImperativeHandle(
131
- parentRef,
132
- () => ({
133
- formRef,
134
- }),
135
- [],
136
- );
137
-
138
- useEffect(() => {
139
- if (formRef.current) {
140
- setVal(props.list);
141
- }
142
- }, [props.list]);
143
-
144
- useEffect(() => {
145
- // 动态设置 table props 值
146
- formRef.current.formRender.setFieldState("arrayTable", (state) => {
147
- let rowSelection;
148
- if (config.rowSelection || tableProps?.rowSelection) {
149
- rowSelection = {
150
- ...state.componentProps?.rowSelection,
151
- ...tableProps?.rowSelection,
152
- ...config.rowSelection,
153
- selectedRowKeys: config.rowSelection?.selectedRowKeys || tableProps?.rowSelection?.selectedRowKeys,
154
- };
155
- }
156
- state.componentProps = {
157
- ...state.componentProps,
158
- ...tableProps,
159
- rowSelection,
160
- };
161
- });
162
- }, [config.rowSelection?.selectedRowKeys, tableProps]);
163
-
164
- function getVal() {
165
- return cloneDeep(formRef.current.formRender.values.arrayTable);
166
- }
167
-
168
- function setVal(val) {
169
- // formRef.current.formRender.reset();
170
- formRef.current.formRender.setValues({
171
- arrayTable: cloneDeep(val),
172
- });
173
- }
174
-
175
- async function onEdit() {
176
- setLoading(true);
177
- if (topProps.fetchOnEdit !== false) {
178
- // 获取当前列表最新数据
179
- return getList()
180
- .then((res) => {
181
- handleEdit(res?.list);
182
- return res;
183
- })
184
- .catch((err) => {
185
- console.error("err", err);
186
- handleMessage(err._message);
187
- return Promise.reject(err);
188
- });
189
- } else {
190
- const value = getVal();
191
- handleEdit(value);
192
- return Promise.resolve(value);
193
- }
194
- }
195
-
196
- async function handleEdit(data) {
197
- // cloneDeep 避免受影响
198
- preValRef.current = cloneDeep(data);
199
- setVal(data);
200
- setEditing(true);
201
- formRef.current.formRender.fields.arrayTable.readPretty = false;
202
- setLoading(false);
203
- }
204
-
205
- async function onSubmit() {
206
- setLoading(true);
207
- try {
208
- // 表单校验
209
- await formRef.current?.formRender?.validate();
210
- try {
211
- await (props.onEditSubmit && props.onEditSubmit(getVal()));
212
- onClose();
213
- } catch (error) {}
214
- } catch (error) {
215
- console.error("Error validate: ", error);
216
- !topProps.hideMessage && handleMessage("输入有误!");
217
- }
218
- setLoading(false);
219
- }
220
-
221
- function onClose() {
222
- formRef.current.formRender.fields.arrayTable.readPretty = true;
223
- setEditing(false);
224
- }
225
-
226
- function onCancel() {
227
- onClose();
228
- // 未提交,取消恢复原始数据
229
- setVal(preValRef.current);
230
- }
231
-
232
- return (
233
- <div className="edit-array-table">
234
- <div className="edit-array-table-head">
235
- <div></div>
236
- <div className="edit-array-table-actions">
237
- {editing ? (
238
- <>
239
- <Button className="edit-array-table-submit" type="primary" onClick={onSubmit} loading={loading}>
240
- 提交
241
- </Button>
242
- <Button className="edit-array-table-cancel" onClick={onCancel} loading={loading}>
243
- 取消
244
- </Button>
245
- </>
246
- ) : (
247
- <Button className="edit-array-table-edit" type="primary" onClick={onEdit} loading={loading}>
248
- 编辑
249
- </Button>
250
- )}
251
- </div>
252
- </div>
253
- <FormRender
254
- ref={formRef}
255
- className="edit-array-table-form"
256
- schema={schema}
257
- components={components}
258
- schemaScope={{
259
- ...schemaScope,
260
- _data: {
261
- selectedRowKeys: config?.rowSelection?.selectedRowKeys,
262
- },
263
- }}
264
- initialValues={{}}
265
- emptyValue={" "}
266
- formOptions={{ readPretty: editMode !== "table-edit-show" }}
267
- />
268
- </div>
269
- );
270
- });
271
-
272
- export default EditArrayTable;
@@ -1,158 +0,0 @@
1
- import React, { useRef } from "react";
2
- import { EditOutlined, CheckOutlined, CloseOutlined } from "@ant-design/icons";
3
- import { useForm } from "@formily/react";
4
-
5
- import { Item, EditMode } from "./type";
6
-
7
- const submitHideList = ["line"];
8
-
9
- export interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
10
- SchemaField: any;
11
- getField: () => {
12
- type: string;
13
- name: string;
14
- component: string;
15
- };
16
- editing: boolean;
17
- dataIndex: string;
18
- title: any;
19
- inputType: "number" | "text";
20
- record: Item;
21
- index: number;
22
- editable: boolean;
23
- onEdit: (record: Partial<Item> & { key: React.Key }, dataIndex: string, opt: Object) => void;
24
- onEditSave: ({ field, id, dataIndex }) => void;
25
- onCancel: () => void;
26
- topProps: {
27
- hasEdit: boolean | Function;
28
- tableConf: { canEdit: Function };
29
- editMode: EditMode;
30
- idKey: "string";
31
- };
32
- components: any;
33
- children: React.ReactNode;
34
- }
35
-
36
- export const EditableCell: React.FC<EditableCellProps> = ({
37
- SchemaField,
38
- getField,
39
- editing,
40
- dataIndex,
41
- title,
42
- inputType,
43
- record,
44
- index,
45
- onEdit,
46
- onEditSave,
47
- onCancel,
48
- editable,
49
- topProps,
50
- children,
51
- components,
52
- ...restProps
53
- }) => {
54
- const field = getField && getField();
55
- const { idKey = "id", hasEdit, editMode = "modal" } = topProps || {};
56
- const { canEdit } = topProps?.tableConf || {};
57
-
58
- // 弹窗编辑模式
59
- if (!field || (typeof canEdit === "function" && canEdit(record, { index, field }))) {
60
- return <td {...restProps}>{children}</td>;
61
- }
62
-
63
- const name = field?.name;
64
- const fieldRef = useRef();
65
- const fPattern = field?.["x-pattern"];
66
- const fDisplay = field?.["x-display"];
67
- const display = field?.["x-display"];
68
- const disabled = display === "none" || display === "hidden";
69
-
70
- const id = record?.[idKey];
71
- // 无编辑权限或禁止编辑
72
- const _hasEdit = hasEdit && typeof hasEdit === "function" ? hasEdit(record, index) : hasEdit !== false;
73
- let _editable =
74
- !disabled && _hasEdit && editable && !(fPattern === "disabled" || fPattern === "readOnly" || fDisplay === "none");
75
- // 行内单元格编辑按钮
76
- const showEditIcon = !editing && _editable && (editMode === "line-cell" || editMode === "cell");
77
- const showSubmitIcon = !disabled && editing && !submitHideList.includes(editMode);
78
-
79
- const editOpt = { index, field, fieldRef };
80
-
81
- const form = useForm();
82
- // 表单项禁用状态
83
- if (form.fields[name]) {
84
- form.fields[name].pattern = disabled || !editing ? "readPretty" : field?.["x-pattern"] ?? "editable";
85
- }
86
-
87
- // 使用 Schema 渲染模式
88
- return (
89
- <td {...restProps}>
90
- <div
91
- className="editable-table-cell table-cell"
92
- onDoubleClick={(e) => {
93
- if (editMode == "modal") {
94
- return;
95
- }
96
- if (editing) {
97
- return;
98
- }
99
- e?.preventDefault();
100
- e?.stopPropagation();
101
- onEdit(record, dataIndex, editOpt);
102
- }}
103
- onKeyDown={(e) => {
104
- if (e.key === "Enter") {
105
- e.preventDefault(); // 防止意外的表单提交
106
- onEditSave && onEditSave({ field, id, dataIndex });
107
- }
108
- }}
109
- >
110
- <SchemaField
111
- schema={{
112
- type: "object",
113
- properties: {
114
- [name]: {
115
- ...field,
116
- title: "",
117
- ["x-component-props"]: {
118
- ...field["x-component-props"],
119
- ref: (ref) => {
120
- if (field["x-component-props"] && typeof field["x-component-props"].ref === "function") {
121
- field["x-component-props"].ref(ref);
122
- }
123
- if (ref) {
124
- fieldRef.current = ref;
125
- }
126
- },
127
- record,
128
- index,
129
- },
130
- // 外部配置的表单显隐状态,强制为 显示
131
- "x-display": "visible",
132
- },
133
- },
134
- }}
135
- />
136
- {showEditIcon ? (
137
- <EditOutlined
138
- className="table-cell-edit-icon"
139
- onClick={(e) => {
140
- e?.preventDefault();
141
- e?.stopPropagation();
142
- onEdit(record, dataIndex, editOpt);
143
- }}
144
- />
145
- ) : null}
146
- {showSubmitIcon ? (
147
- <div className="cell-editing-actions">
148
- <CheckOutlined
149
- className="table-cell-confirm-icon"
150
- onClick={() => onEditSave({ field, id: record[topProps.idKey || "id"], dataIndex })}
151
- />
152
- <CloseOutlined className="table-cell-cancel-icon" onClick={onCancel} />
153
- </div>
154
- ) : null}
155
- </div>
156
- </td>
157
- );
158
- };
@@ -1,75 +0,0 @@
1
- import { useMemo } from "react";
2
- import { Form } from "antd";
3
- import { createForm, onFormValuesChange, onFieldValueChange, Field } from "@formily/core";
4
- import { FormProvider, FormConsumer } from "@formily/react";
5
- import { PreviewText } from "c-formily-antd/lib/preview-text";
6
-
7
- import { Item, EditMode } from "./type";
8
-
9
- export interface EditableRowProps extends React.HTMLAttributes<HTMLElement> {
10
- rowFormMapRef;
11
- editingInofRef;
12
- record: Item;
13
- editable: boolean;
14
- disabled: boolean;
15
- onEditSave;
16
- topProps: {
17
- config: { hasEdit: boolean | Function };
18
- editMode: EditMode;
19
- idKey: "string";
20
- onFormValuesChange: (form: any) => void;
21
- onFieldValueChange: (field, form: any) => void;
22
- formOptions: {
23
- effects;
24
- };
25
- tableConf: {
26
- tableEmptyValue;
27
- };
28
- };
29
- children: React.ReactNode;
30
- }
31
-
32
- export const EditTableRow: React.FC<EditableRowProps> = (props: EditableRowProps) => {
33
- const { record, rowFormMapRef, editingInofRef, topProps, onEditSave, ...resetProps } = props;
34
- const { idKey = "id", editMode } = topProps || {};
35
- const rowId = props["data-row-key"];
36
- const rowForm = useMemo(() => {
37
- if (rowFormMapRef?.current?.get && rowFormMapRef.current.get(rowId)) {
38
- // @ts-ignore
39
- rowFormMapRef.current.get(rowId).readPretty = true;
40
- return rowFormMapRef.current?.get(rowId);
41
- }
42
- const form = createForm({
43
- initialValues: record,
44
- // 只读模式,非编辑态默认为只读模式
45
- readPretty: editingInofRef?.current?.editingRowId !== rowId,
46
- ...(topProps?.formOptions || {}),
47
- effects(...args) {
48
- topProps?.onFormValuesChange && onFormValuesChange(topProps.onFormValuesChange);
49
- onFieldValueChange("*", (field: Field, form) => {
50
- topProps.onFieldValueChange && topProps.onFieldValueChange(field, form);
51
- });
52
- topProps?.formOptions?.effects && topProps.formOptions?.effects(...args);
53
- },
54
- });
55
- if (rowFormMapRef) {
56
- rowFormMapRef.current.set(rowId, form);
57
- }
58
-
59
- if (record) {
60
- form.setValues(record);
61
- }
62
- return form;
63
- }, [record]);
64
-
65
- return (
66
- <FormProvider form={rowForm}>
67
- {/* 传入空值展示的字符串 */}
68
- <PreviewText.Placeholder value={topProps?.tableConf?.tableEmptyValue || " "}>
69
- <Form layout="vertical" component={false}>
70
- <FormConsumer>{() => <tr {...resetProps}>{props.children}</tr>}</FormConsumer>
71
- </Form>
72
- </PreviewText.Placeholder>
73
- </FormProvider>
74
- );
75
- };