@hzab/list-render 1.10.2-beta → 1.10.4
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 +4 -0
- package/README.md +2 -1
- package/package.json +1 -1
- package/src/common/constant.ts +4 -0
- package/src/common/handleQuerySchema.ts +576 -302
- package/src/components/Formily/FormilyField.tsx +68 -68
- package/src/list-render.jsx +74 -16
- package/src/query-render/index.jsx +95 -92
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
import { memo, useEffect, useState, useMemo, useCallback, useRef } from "react";
|
|
2
|
-
import { createForm } from "@formily/core";
|
|
3
|
-
import { createSchemaField, useField, useFieldSchema, observer, FormProvider, Schema } from "@formily/react";
|
|
4
|
-
import { Form } from "c-formily-antd";
|
|
5
|
-
import { handleReaction } from "../../common/handleReactions";
|
|
6
|
-
|
|
7
|
-
import { antdComponents, customComponents } from "@hzab/form-render";
|
|
8
|
-
|
|
9
|
-
type formilyFieldPropsT = {
|
|
10
|
-
schema: Schema;
|
|
11
|
-
formilyRef: any;
|
|
12
|
-
schemaScope: Object;
|
|
13
|
-
components: Object;
|
|
14
|
-
reactionOpts?: Object;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
// TODO: 借住 formily 核心代码实现相关数据响应
|
|
18
|
-
// 页面中加载 formily,以此获取到 field、fieldSchema 等数据
|
|
19
|
-
export const FormilyField = memo(function (props: formilyFieldPropsT) {
|
|
20
|
-
const { schema, formilyRef, schemaScope, components, reactionOpts } = props;
|
|
21
|
-
const { fields, fieldSchemas } = formilyRef.current || {};
|
|
22
|
-
const SchemaField = useCallback(
|
|
23
|
-
createSchemaField({
|
|
24
|
-
// @ts-ignore
|
|
25
|
-
components: {
|
|
26
|
-
...antdComponents,
|
|
27
|
-
...customComponents,
|
|
28
|
-
...components,
|
|
29
|
-
FormItem(props) {
|
|
30
|
-
const field = useField();
|
|
31
|
-
const fieldSchema = useFieldSchema();
|
|
32
|
-
const { name } = fieldSchema;
|
|
33
|
-
fields[name] = field;
|
|
34
|
-
fieldSchemas[name] = fieldSchema;
|
|
35
|
-
// 处理自定义的变量
|
|
36
|
-
handleReaction(fieldSchema, { ...reactionOpts, scope: schemaScope });
|
|
37
|
-
const Com = antdComponents?.FormItem;
|
|
38
|
-
return Com && <Com {...props} />;
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
scope: { ...schemaScope },
|
|
42
|
-
}),
|
|
43
|
-
[],
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
const formRender = useMemo(
|
|
47
|
-
() =>
|
|
48
|
-
createForm({
|
|
49
|
-
initialValues: {},
|
|
50
|
-
// 禁用状态(注意,自定义组件组件自行获取对应的状态)
|
|
51
|
-
readOnly: true,
|
|
52
|
-
disabled: true,
|
|
53
|
-
}),
|
|
54
|
-
[],
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
return (
|
|
58
|
-
<Form
|
|
59
|
-
className={`hidden-table-form-render`}
|
|
60
|
-
style={{ display: "none", width: 0, height: 0, overflow: "hidden" }}
|
|
61
|
-
form={formRender}
|
|
62
|
-
>
|
|
63
|
-
<SchemaField schema={schema}></SchemaField>
|
|
64
|
-
</Form>
|
|
65
|
-
);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
export default FormilyField;
|
|
1
|
+
import { memo, useEffect, useState, useMemo, useCallback, useRef } from "react";
|
|
2
|
+
import { createForm } from "@formily/core";
|
|
3
|
+
import { createSchemaField, useField, useFieldSchema, observer, FormProvider, Schema } from "@formily/react";
|
|
4
|
+
import { Form } from "c-formily-antd";
|
|
5
|
+
import { handleReaction } from "../../common/handleReactions";
|
|
6
|
+
|
|
7
|
+
import { antdComponents, customComponents } from "@hzab/form-render";
|
|
8
|
+
|
|
9
|
+
type formilyFieldPropsT = {
|
|
10
|
+
schema: Schema;
|
|
11
|
+
formilyRef: any;
|
|
12
|
+
schemaScope: Object;
|
|
13
|
+
components: Object;
|
|
14
|
+
reactionOpts?: Object;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// TODO: 借住 formily 核心代码实现相关数据响应
|
|
18
|
+
// 页面中加载 formily,以此获取到 field、fieldSchema 等数据
|
|
19
|
+
export const FormilyField = memo(function (props: formilyFieldPropsT) {
|
|
20
|
+
const { schema, formilyRef, schemaScope, components, reactionOpts } = props;
|
|
21
|
+
const { fields, fieldSchemas } = formilyRef.current || {};
|
|
22
|
+
const SchemaField = useCallback(
|
|
23
|
+
createSchemaField({
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
components: {
|
|
26
|
+
...antdComponents,
|
|
27
|
+
...customComponents,
|
|
28
|
+
...components,
|
|
29
|
+
FormItem(props) {
|
|
30
|
+
const field = useField();
|
|
31
|
+
const fieldSchema = useFieldSchema();
|
|
32
|
+
const { name } = fieldSchema;
|
|
33
|
+
fields[name] = field;
|
|
34
|
+
fieldSchemas[name] = fieldSchema;
|
|
35
|
+
// 处理自定义的变量
|
|
36
|
+
handleReaction(fieldSchema, { ...reactionOpts, scope: schemaScope });
|
|
37
|
+
const Com = antdComponents?.FormItem;
|
|
38
|
+
return Com && <Com {...props} />;
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
scope: { ...schemaScope },
|
|
42
|
+
} as any),
|
|
43
|
+
[],
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const formRender = useMemo(
|
|
47
|
+
() =>
|
|
48
|
+
createForm({
|
|
49
|
+
initialValues: {},
|
|
50
|
+
// 禁用状态(注意,自定义组件组件自行获取对应的状态)
|
|
51
|
+
readOnly: true,
|
|
52
|
+
disabled: true,
|
|
53
|
+
}),
|
|
54
|
+
[],
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<Form
|
|
59
|
+
className={`hidden-table-form-render`}
|
|
60
|
+
style={{ display: "none", width: 0, height: 0, overflow: "hidden" }}
|
|
61
|
+
form={formRender}
|
|
62
|
+
>
|
|
63
|
+
<SchemaField schema={schema}></SchemaField>
|
|
64
|
+
</Form>
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export default FormilyField;
|
package/src/list-render.jsx
CHANGED
|
@@ -15,6 +15,13 @@ import FormModal from "./FormModal";
|
|
|
15
15
|
import DetailModal from "./DetailModal";
|
|
16
16
|
|
|
17
17
|
import { objToFormData } from "./common/utils";
|
|
18
|
+
import {
|
|
19
|
+
setURLObjectQueryParam,
|
|
20
|
+
getURLObjectQueryParam,
|
|
21
|
+
removeURLObjectQueryParam,
|
|
22
|
+
extractSplitDateRanges,
|
|
23
|
+
} from "./common/handleQuerySchema";
|
|
24
|
+
import { CLEAR_LIST, URL_PARAM_NAME } from "./common/constant";
|
|
18
25
|
|
|
19
26
|
import "./index.less";
|
|
20
27
|
|
|
@@ -43,6 +50,16 @@ const ListRender = forwardRef(function (props, parentRef) {
|
|
|
43
50
|
* 表单提交是否使用 FormData 格式
|
|
44
51
|
*/
|
|
45
52
|
useFormData: _useFormData,
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 筛选条件改变时是否将参数(对象形式)设置到url query中
|
|
56
|
+
* */
|
|
57
|
+
appendUrlQuery = false,
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 自定义设置url query对象参数的key
|
|
61
|
+
* */
|
|
62
|
+
appendUrlQueryKey = URL_PARAM_NAME,
|
|
46
63
|
} = props;
|
|
47
64
|
const pageSizeOptions = props.paginationConf?.pageSizeOptions || pageSizeOptionMap[props.layout] || [10, 20, 50, 100];
|
|
48
65
|
// const [pageSizeOptions, setPageSizeOptions] = useState(
|
|
@@ -77,7 +94,7 @@ const ListRender = forwardRef(function (props, parentRef) {
|
|
|
77
94
|
onDel,
|
|
78
95
|
}));
|
|
79
96
|
|
|
80
|
-
const { schema = {}, config = {}, model = {}, msgConf = {} } = props;
|
|
97
|
+
const { schema = {}, config = {}, model = {}, msgConf = {}, filters } = props;
|
|
81
98
|
|
|
82
99
|
// useEffect(() => {
|
|
83
100
|
// const list = props.paginationConf?.pageSizeOptions || pageSizeOptionMap[props.layout] || [10, 20, 50, 100];
|
|
@@ -86,20 +103,34 @@ const ListRender = forwardRef(function (props, parentRef) {
|
|
|
86
103
|
// }, [layout]);
|
|
87
104
|
|
|
88
105
|
useEffect(() => {
|
|
106
|
+
const getUrlQuery = appendUrlQuery ? getURLObjectQueryParam(appendUrlQueryKey) : {};
|
|
107
|
+
|
|
89
108
|
if (model) {
|
|
90
109
|
if (!model.query) {
|
|
91
110
|
model.query = {};
|
|
92
111
|
} else {
|
|
112
|
+
model.query.pageNum = 1;
|
|
113
|
+
|
|
93
114
|
modelQueryRef.current = model?.query;
|
|
94
115
|
paginationQueryRef.current = {
|
|
95
|
-
pageNum: model?.query?.pageNum
|
|
96
|
-
pageSize: model?.query?.pageSize
|
|
116
|
+
pageNum: getUrlQuery?.pageNum || model?.query?.pageNum || paginationQueryRef.current?.pageNum,
|
|
117
|
+
pageSize: getUrlQuery?.pageSize || model?.query?.pageSize || paginationQueryRef.current?.pageSize,
|
|
97
118
|
};
|
|
98
119
|
}
|
|
99
|
-
model.query.pageNum = 1;
|
|
100
120
|
}
|
|
101
|
-
|
|
102
|
-
|
|
121
|
+
|
|
122
|
+
// 延迟获取表单实例
|
|
123
|
+
Promise.resolve().then(() => {
|
|
124
|
+
if (queryRef.current && queryRef.current?.formRef?.current.formRender) {
|
|
125
|
+
const extractValues = extractSplitDateRanges(filters, schema, getUrlQuery);
|
|
126
|
+
|
|
127
|
+
queryRef.current.formRef.current.formRender?.setValues(extractValues);
|
|
128
|
+
|
|
129
|
+
formQueryRef.current = _.cloneDeep(getUrlQuery);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
!props.closeAutoRequest && getList({ ...(modelQueryRef.current || {}), ...getUrlQuery });
|
|
103
134
|
}, []);
|
|
104
135
|
|
|
105
136
|
useEffect(() => {
|
|
@@ -156,7 +187,6 @@ const ListRender = forwardRef(function (props, parentRef) {
|
|
|
156
187
|
}
|
|
157
188
|
|
|
158
189
|
// model.query = mergedQueries;
|
|
159
|
-
|
|
160
190
|
// 取消上一次请求
|
|
161
191
|
getListSourceRef.current?.cancel({ code: 601, message: "取消上一次请求" });
|
|
162
192
|
|
|
@@ -196,11 +226,19 @@ const ListRender = forwardRef(function (props, parentRef) {
|
|
|
196
226
|
// model.query.pageNum = page;
|
|
197
227
|
// model.query.pageSize = size;
|
|
198
228
|
paginationQueryRef.current = { pageNum: page, pageSize: size };
|
|
229
|
+
|
|
230
|
+
if (appendUrlQuery) {
|
|
231
|
+
const getUrlQuery = getURLObjectQueryParam(appendUrlQueryKey);
|
|
232
|
+
setURLObjectQueryParam({ ...getUrlQuery, ...paginationQueryRef.current }, appendUrlQueryKey);
|
|
233
|
+
}
|
|
199
234
|
getList();
|
|
200
235
|
}
|
|
201
236
|
|
|
202
|
-
function onSearch(quer, source) {
|
|
237
|
+
function onSearch(quer, source, isReset = false) {
|
|
203
238
|
const query = source === "queryRender" ? { ...quer } : { ...formQueryRef.current, ...quer };
|
|
239
|
+
// 重置操作时不赋值
|
|
240
|
+
if (source === "queryRender" && !isReset && appendUrlQuery) setURLObjectQueryParam(query, appendUrlQueryKey);
|
|
241
|
+
|
|
204
242
|
if (model && !model.query) {
|
|
205
243
|
model.query = {};
|
|
206
244
|
}
|
|
@@ -215,6 +253,28 @@ const ListRender = forwardRef(function (props, parentRef) {
|
|
|
215
253
|
getList(query);
|
|
216
254
|
}
|
|
217
255
|
|
|
256
|
+
function handleFormReset() {
|
|
257
|
+
appendUrlQuery && removeURLObjectQueryParam(appendUrlQueryKey, "", true);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function handleFieldValueChange(filed, form) {
|
|
261
|
+
// props?.onFieldValueChange?.(filed, form);
|
|
262
|
+
|
|
263
|
+
if (!appendUrlQuery) return;
|
|
264
|
+
|
|
265
|
+
try {
|
|
266
|
+
const { componentType, value, path } = filed;
|
|
267
|
+
if (CLEAR_LIST.includes(componentType)) {
|
|
268
|
+
if (value === "" || value?.length === 0 || value === undefined) {
|
|
269
|
+
const key = path.entire;
|
|
270
|
+
key && removeURLObjectQueryParam(appendUrlQueryKey, key);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
} catch (e) {
|
|
274
|
+
console.error("url参数清除失败", e);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
218
278
|
function forceUpdate() {
|
|
219
279
|
setList((l) => _.cloneDeep(l));
|
|
220
280
|
}
|
|
@@ -375,17 +435,15 @@ const ListRender = forwardRef(function (props, parentRef) {
|
|
|
375
435
|
search={props.search}
|
|
376
436
|
filters={props.filters}
|
|
377
437
|
config={props.queryConf}
|
|
378
|
-
queryFormInitialValues={
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
...model.query,
|
|
383
|
-
}
|
|
384
|
-
: queryFormInitialValues
|
|
385
|
-
}
|
|
438
|
+
queryFormInitialValues={{
|
|
439
|
+
...queryFormInitialValues,
|
|
440
|
+
...(queryFormIsExtendModelQuery ? model.query : {}),
|
|
441
|
+
}}
|
|
386
442
|
onSearch={onSearch}
|
|
443
|
+
onReset={handleFormReset}
|
|
387
444
|
schemaScope={props.schemaScope}
|
|
388
445
|
components={props.components}
|
|
446
|
+
onFieldValueChange={handleFieldValueChange}
|
|
389
447
|
i18n={i18n}
|
|
390
448
|
/>
|
|
391
449
|
) : (
|
|
@@ -1,92 +1,95 @@
|
|
|
1
|
-
import { useState, useRef, useEffect, useImperativeHandle, forwardRef } from "react";
|
|
2
|
-
import { Button } from "antd";
|
|
3
|
-
import dayjs from "dayjs";
|
|
4
|
-
import _ from "lodash";
|
|
5
|
-
|
|
6
|
-
import FormRender from "@hzab/form-render";
|
|
7
|
-
import { handleQuerySchema } from "../common/handleQuerySchema";
|
|
8
|
-
|
|
9
|
-
import "./index.less";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
query.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
query.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
1
|
+
import { useState, useRef, useEffect, useImperativeHandle, forwardRef } from "react";
|
|
2
|
+
import { Button } from "antd";
|
|
3
|
+
import dayjs from "dayjs";
|
|
4
|
+
import _ from "lodash";
|
|
5
|
+
|
|
6
|
+
import FormRender from "@hzab/form-render";
|
|
7
|
+
import { handleQuerySchema } from "../common/handleQuerySchema";
|
|
8
|
+
|
|
9
|
+
import "./index.less";
|
|
10
|
+
import { onFieldValueChange } from "@formily/core";
|
|
11
|
+
|
|
12
|
+
function QueryRender(props, parentRef) {
|
|
13
|
+
const [schema, setSchema] = useState({});
|
|
14
|
+
const formRef = useRef();
|
|
15
|
+
|
|
16
|
+
useImperativeHandle(parentRef, () => ({ formRef }));
|
|
17
|
+
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
setSchema(
|
|
20
|
+
handleQuerySchema({
|
|
21
|
+
...props?.config,
|
|
22
|
+
schemaScope: { ...props.schemaScope, scenario: "query" },
|
|
23
|
+
schema: _.cloneDeep(props.schema),
|
|
24
|
+
search: props.search,
|
|
25
|
+
filters: _.cloneDeep(props.filters),
|
|
26
|
+
onSearch,
|
|
27
|
+
}),
|
|
28
|
+
);
|
|
29
|
+
}, [props.search, props.filters, props.schema, props.schema?.schema]);
|
|
30
|
+
|
|
31
|
+
async function onSearch() {
|
|
32
|
+
let query = _.cloneDeep(formRef?.current?.formRender?.values);
|
|
33
|
+
if (props.filters?.includes("$timerange")) {
|
|
34
|
+
if (query.$timerange?.[0] instanceof dayjs) {
|
|
35
|
+
query.beginTime = query.$timerange?.[0]?.format("YYYY-MM-DD HH:mm:ss");
|
|
36
|
+
query.endTime = query.$timerange?.[1]?.format("YYYY-MM-DD HH:mm:ss");
|
|
37
|
+
} else {
|
|
38
|
+
query.beginTime = query.$timerange?.[0];
|
|
39
|
+
query.endTime = query.$timerange?.[1];
|
|
40
|
+
}
|
|
41
|
+
delete query.$timerange;
|
|
42
|
+
}
|
|
43
|
+
if (props.config?.queryMap) {
|
|
44
|
+
query = props.config?.queryMap(query);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (props.config?.beforeQuerySearch && typeof props.config?.beforeQuerySearch === "function") {
|
|
48
|
+
// 处理 beforeQuerySearch 为同步或者异步函数的情况
|
|
49
|
+
const beforeQuerySearchResult = await Promise.resolve(props.config?.beforeQuerySearch?.(query));
|
|
50
|
+
|
|
51
|
+
if (!beforeQuerySearchResult) return;
|
|
52
|
+
}
|
|
53
|
+
return props.onSearch && props.onSearch(query, "queryRender");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function onReset() {
|
|
57
|
+
formRef.current?.formRender?.reset();
|
|
58
|
+
props.onReset?.();
|
|
59
|
+
props.onSearch && props.onSearch(_.cloneDeep(formRef?.current?.formRender?.values), "queryRender", true);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<div className="query-render">
|
|
64
|
+
{Object.keys(schema?.schema?.properties || {}).length > 0 ? (
|
|
65
|
+
<>
|
|
66
|
+
<FormRender
|
|
67
|
+
ref={formRef}
|
|
68
|
+
layout="inline"
|
|
69
|
+
schema={schema}
|
|
70
|
+
schemaScope={{ scenario: "query", ...(props.schemaScope || {}) }}
|
|
71
|
+
initialValues={props.queryFormInitialValues}
|
|
72
|
+
onFieldValueChange={props.onFieldValueChange}
|
|
73
|
+
Slots={() => {
|
|
74
|
+
return (
|
|
75
|
+
<div className="query-operation">
|
|
76
|
+
<Button className="query-btn" type="primary" onClick={onSearch}>
|
|
77
|
+
搜索
|
|
78
|
+
</Button>
|
|
79
|
+
{props.config?.hasReset && (
|
|
80
|
+
<Button className="query-btn" onClick={onReset}>
|
|
81
|
+
重置
|
|
82
|
+
</Button>
|
|
83
|
+
)}
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}}
|
|
87
|
+
components={props.components}
|
|
88
|
+
></FormRender>
|
|
89
|
+
</>
|
|
90
|
+
) : null}
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export default forwardRef(QueryRender);
|