@hzab/list-render 1.10.2 → 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.
@@ -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;
@@ -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 ?? paginationQueryRef.current?.pageNum,
96
- pageSize: model?.query?.pageSize ?? paginationQueryRef.current?.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
- !props.closeAutoRequest && onSearch(queryFormInitialValues);
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
- queryFormIsExtendModelQuery
380
- ? {
381
- ...queryFormInitialValues,
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
- function QueryRender(props, parentRef) {
12
- const [schema, setSchema] = useState({});
13
- const formRef = useRef();
14
-
15
- useImperativeHandle(parentRef, () => ({ formRef }));
16
-
17
- useEffect(() => {
18
- setSchema(
19
- handleQuerySchema({
20
- ...props?.config,
21
- schemaScope: { ...props.schemaScope, scenario: "query" },
22
- schema: _.cloneDeep(props.schema),
23
- search: props.search,
24
- filters: _.cloneDeep(props.filters),
25
- onSearch,
26
- }),
27
- );
28
- }, [props.search, props.filters, props.schema, props.schema?.schema]);
29
-
30
- async function onSearch() {
31
- let query = _.cloneDeep(formRef?.current?.formRender?.values);
32
- if (props.filters?.includes("$timerange")) {
33
- if (query.$timerange?.[0] instanceof dayjs) {
34
- query.beginTime = query.$timerange?.[0]?.format("YYYY-MM-DD HH:mm:ss");
35
- query.endTime = query.$timerange?.[1]?.format("YYYY-MM-DD HH:mm:ss");
36
- } else {
37
- query.beginTime = query.$timerange?.[0];
38
- query.endTime = query.$timerange?.[1];
39
- }
40
- delete query.$timerange;
41
- }
42
- if (props.config?.queryMap) {
43
- query = props.config?.queryMap(query);
44
- }
45
-
46
- if (props.config?.beforeQuerySearch && typeof props.config?.beforeQuerySearch === "function") {
47
- // 处理 beforeQuerySearch 为同步或者异步函数的情况
48
- const beforeQuerySearchResult = await Promise.resolve(props.config?.beforeQuerySearch?.(query));
49
-
50
- if (!beforeQuerySearchResult) return;
51
- }
52
- return props.onSearch && props.onSearch(query, "queryRender");
53
- }
54
-
55
- function onReset() {
56
- formRef.current?.formRender?.reset();
57
- props.onSearch && props.onSearch(_.cloneDeep(formRef?.current?.formRender?.values), "queryRender");
58
- }
59
-
60
- return (
61
- <div className="query-render">
62
- {Object.keys(schema?.schema?.properties || {}).length > 0 ? (
63
- <>
64
- <FormRender
65
- ref={formRef}
66
- layout="inline"
67
- schema={schema}
68
- schemaScope={{ scenario: "query", ...(props.schemaScope || {}) }}
69
- initialValues={props.queryFormInitialValues}
70
- Slots={() => {
71
- return (
72
- <div className="query-operation">
73
- <Button className="query-btn" type="primary" onClick={onSearch}>
74
- 搜索
75
- </Button>
76
- {props.config?.hasReset && (
77
- <Button className="query-btn" onClick={onReset}>
78
- 重置
79
- </Button>
80
- )}
81
- </div>
82
- );
83
- }}
84
- components={props.components}
85
- ></FormRender>
86
- </>
87
- ) : null}
88
- </div>
89
- );
90
- }
91
-
92
- export default forwardRef(QueryRender);
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);