@cloudbase/weda-ui 3.19.0 → 3.20.1
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/dist/configs/components/wd-form.d.ts +2 -2
- package/dist/configs/components/wd-form.js +2 -2
- package/dist/configs/components/wd-table.d.ts +3 -3
- package/dist/configs/index.d.ts +6 -6
- package/dist/configs/type-utils/type-form.d.ts +2 -2
- package/dist/style/weda-ui.min.css +1 -1
- package/dist/web/components/form-input-hooks/index.d.ts +3 -1
- package/dist/web/components/form-input-hooks/index.js +93 -54
- package/dist/web/components/form-rich-text/index.d.ts +3 -3
- package/dist/web/components/form-rich-text/index.js +8 -4
- package/dist/web/components/formdetail/index.d.ts +1 -1
- package/dist/web/components/formdetail/index.js +28 -42
- package/dist/web/components/richText/index.js +9 -3
- package/dist/web/components/wd-form/contexts/form-field-arr-context.d.ts +21 -0
- package/dist/web/components/wd-form/contexts/form-field-arr-context.js +10 -0
- package/dist/web/components/wd-form/contexts/form-field-context.d.ts +19 -0
- package/dist/web/components/wd-form/contexts/form-field-context.js +10 -0
- package/dist/web/components/wd-form/contexts/form-field-obj-context.d.ts +13 -0
- package/dist/web/components/wd-form/contexts/form-field-obj-context.js +10 -0
- package/dist/web/components/wd-form/index.d.ts +4 -4
- package/dist/web/components/wd-form/index.js +142 -191
- package/dist/web/components/wd-form-item/wd-form-item.d.ts +2 -2
- package/dist/web/components/wd-form-item/wd-form-item.js +96 -14
- package/dist/web/components/wd-form-obj/base-form-obj.js +66 -197
- package/dist/web/components/wd-input/wd-input.js +1 -1
- package/dist/web/components/wd-input-number/wd-input-number.js +43 -17
- package/dist/web/components/wd-rich-text/wd-rich-text.d.ts +1 -1
- package/dist/web/components/wd-rich-text/wd-rich-text.js +7 -3
- package/dist/web/components/wd-select/select/selectUI.js +9 -2
- package/dist/web/utils/widget-api/index.d.ts +0 -14
- package/dist/web/utils/widget-api/index.js +0 -7
- package/package.json +1 -1
|
@@ -1,43 +1,39 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
/* eslint max-lines: [error, 800] */
|
|
3
|
-
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState
|
|
4
|
-
import { useMap, useMountEffect, useSyncedRef, useUnmountEffect, } from '@react-hookz/web';
|
|
5
|
-
import { unstable_batchedUpdates } from 'react-dom';
|
|
3
|
+
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { useMap, useMountEffect, useSyncedRef, useUnmountEffect, useDebouncedEffect } from '@react-hookz/web';
|
|
6
5
|
import { errorHandler } from '../../utils/error';
|
|
7
|
-
import {
|
|
6
|
+
import { usePlatform } from '../../utils/platform';
|
|
8
7
|
import classNames from '../../utils/classnames';
|
|
9
8
|
import { debug } from '../../utils/console';
|
|
10
9
|
import { useWedaAppContext } from '../../utils/widget-api';
|
|
11
10
|
import { useLoopRenderDetect } from '../common/use-loop-render-detect';
|
|
12
11
|
import { emptyObject, noop, NOT_EXISTED_VALUE } from '../../utils/constant';
|
|
13
12
|
import * as tcbAppCloud from '../../utils/tcb';
|
|
14
|
-
import { useRemoteValue, useInitValueFromRemote, useRemoteParamsFromValue
|
|
13
|
+
import { useRemoteValue, useInitValueFromRemote, useRemoteParamsFromValue } from './hooks/use-remote-value';
|
|
15
14
|
import { createSetStateForAuth, useAuthValue } from './hooks/use-auth-value';
|
|
16
15
|
import { useSetWidgetApi } from '../../utils/widget-api/use-set-widget-api';
|
|
17
16
|
import lodashGet from 'lodash.get';
|
|
18
|
-
import
|
|
17
|
+
import lodashSet from 'lodash.set';
|
|
19
18
|
import { useDataSource } from '../../utils/hooks/useDataSource';
|
|
20
19
|
import { WdForm as FormUi } from './wd-form';
|
|
21
20
|
import EmptyContent from '../statusContent';
|
|
22
21
|
import { deepClone } from '../../utils/tool';
|
|
22
|
+
import isObjectEqual from '../../utils/isObjectEqual';
|
|
23
23
|
import '../style';
|
|
24
|
-
import { getErrorObjectFromValidateResult
|
|
25
|
-
import { ConfigProvider, StatusTip } from 'tea-component';
|
|
24
|
+
import { getErrorObjectFromValidateResult } from './form-utils';
|
|
26
25
|
import { isNil } from '../../utils/lodash';
|
|
27
26
|
import { FormTypeProvider } from './contexts/form-type-context';
|
|
28
27
|
import { FormLayoutProvider } from './contexts/form-layout-context';
|
|
29
28
|
import { FormWidgetProvider } from './contexts/form-widget-context';
|
|
30
|
-
import
|
|
29
|
+
import { FormFieldProvider } from './contexts/form-field-context';
|
|
31
30
|
import { useSyncValue } from '../../utils/hooks/useSyncValue';
|
|
32
|
-
|
|
33
|
-
// eslint-disable-next-line rulesdir/no-timer
|
|
34
|
-
setTimeout(resolve, ms);
|
|
35
|
-
});
|
|
31
|
+
import useDebouncedCallback from '../../utils/hooks/use-debounced-callback';
|
|
36
32
|
const SET_VALUE_DEBOUNCE_TIMEOUT = 250;
|
|
37
33
|
const logger = debug('wd-form');
|
|
38
34
|
const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
39
|
-
var _a;
|
|
40
|
-
const { className, id, style, contentSlot: contentSlotEl, layout = 'horizontal', formType = 'create', _id, datasourceType = 'model', dataSourceName, methodGetItem, methodCreate, methodUpdate, paramGetItem, appCloud = tcbAppCloud, lgWidth, labelAlign = 'left',
|
|
35
|
+
var _a, _b, _c, _d;
|
|
36
|
+
const { className, id, style, contentSlot: contentSlotEl, layout = 'horizontal', formType = 'create', _id, datasourceType = 'model', dataSourceName, methodGetItem, methodCreate, methodUpdate, paramGetItem, appCloud = tcbAppCloud, lgWidth, labelAlign = 'left', initialValues: _initialValues,
|
|
41
37
|
// 兼容流程setValue调用,其他地方别用
|
|
42
38
|
$node, $widget, } = props;
|
|
43
39
|
const formsItemMap = useMap([]);
|
|
@@ -47,7 +43,8 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
47
43
|
* 所以要用它作useEffect deps的时候用下面这个string
|
|
48
44
|
* */
|
|
49
45
|
const formItemMapKey = [...formsItemMap.keys()].sort().join(',');
|
|
50
|
-
|
|
46
|
+
// 用于存储表单下的一级节点
|
|
47
|
+
const [formItemMapList, setFormItemMapList] = useState([]);
|
|
51
48
|
const platform = usePlatform();
|
|
52
49
|
const isH5 = platform === 'h5';
|
|
53
50
|
const contentSlot = useMemo(() => contentSlotEl, [contentSlotEl]);
|
|
@@ -70,8 +67,42 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
70
67
|
}, [setIsDisabledSubmit]);
|
|
71
68
|
const hasSetInitValueRef = useRef(false);
|
|
72
69
|
const { ready } = useWedaAppContext();
|
|
73
|
-
|
|
70
|
+
// 缓存表单项的初始值
|
|
71
|
+
const [fieldInitValueCache, setFieldInitValueCache] = useState((_a = deepClone(_initialValues)) !== null && _a !== void 0 ? _a : emptyObject);
|
|
72
|
+
// 表单初始值
|
|
73
|
+
const [initialValues, setInitialValues] = useState((_b = deepClone(_initialValues)) !== null && _b !== void 0 ? _b : emptyObject);
|
|
74
74
|
const [propsValue] = useSyncValue(props.value);
|
|
75
|
+
// 表单值
|
|
76
|
+
const [formData, setFormData] = useState((_c = deepClone(_initialValues)) !== null && _c !== void 0 ? _c : emptyObject);
|
|
77
|
+
// 转换后表单值,仅保留已挂载表单项的值
|
|
78
|
+
const [formFieldsValue, setFormFieldsValue] = useState((_d = deepClone(_initialValues)) !== null && _d !== void 0 ? _d : emptyObject);
|
|
79
|
+
useDebouncedEffect(() => {
|
|
80
|
+
var _a, _b;
|
|
81
|
+
// 表单容器上挂载的表单项的值,没有则置空
|
|
82
|
+
const convertFormData = (formData, setNull = false) => {
|
|
83
|
+
const data = {};
|
|
84
|
+
formItemMapList.forEach((i) => {
|
|
85
|
+
const namePath = i;
|
|
86
|
+
const value = lodashGet(formData, namePath, NOT_EXISTED_VALUE);
|
|
87
|
+
// 表单容器内不包含的表单项,不赋值
|
|
88
|
+
if (value !== NOT_EXISTED_VALUE) {
|
|
89
|
+
lodashSet(data, namePath, value);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
if (setNull) {
|
|
93
|
+
lodashSet(data, namePath, null);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
const _fieldInitValueCache = deepClone(fieldInitValueCache);
|
|
98
|
+
return Object.assign(_fieldInitValueCache, data);
|
|
99
|
+
};
|
|
100
|
+
const _data = convertFormData(formData);
|
|
101
|
+
setFormFieldsValue(_data);
|
|
102
|
+
(_b = (_a = eventsRef === null || eventsRef === void 0 ? void 0 : eventsRef.current) === null || _a === void 0 ? void 0 : _a.onDataChange) === null || _b === void 0 ? void 0 : _b.call(_a, { data: _data });
|
|
103
|
+
}, [formData, fieldInitValueCache],
|
|
104
|
+
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
105
|
+
SET_VALUE_DEBOUNCE_TIMEOUT);
|
|
75
106
|
const eventsRef = useSyncedRef(props.events);
|
|
76
107
|
const validate = useCallback(async () => {
|
|
77
108
|
const validatePromise = [];
|
|
@@ -115,6 +146,7 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
115
146
|
return errObj;
|
|
116
147
|
}, [formsItemMap]);
|
|
117
148
|
const [errors, setErrors] = useState(undefined);
|
|
149
|
+
// 用于存储关联关系查询字段
|
|
118
150
|
const allSelectFields = useMemo(() => {
|
|
119
151
|
if (!ready) {
|
|
120
152
|
return null;
|
|
@@ -163,17 +195,13 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
163
195
|
return;
|
|
164
196
|
const run = async () => {
|
|
165
197
|
const { submit, validateSuccess, validateFail } = eventsRef.current;
|
|
166
|
-
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
167
|
-
await timeout(SET_VALUE_DEBOUNCE_TIMEOUT * 2);
|
|
168
198
|
const errorObj = await validate();
|
|
169
199
|
if (Object.keys(errorObj !== null && errorObj !== void 0 ? errorObj : {}).length === 0) {
|
|
170
200
|
validateSuccess({ errors: {} });
|
|
171
|
-
logger.debug('formItemMapKey', formItemMapKey);
|
|
172
|
-
const formData = getFormDataFromItemMap(formsItemMap, formType);
|
|
173
201
|
const extra = ['read', 'edit'].includes(formType) && _id ? { _id } : {};
|
|
174
|
-
submit && submit(deepClone({ ...extra, ...
|
|
202
|
+
submit && submit(deepClone({ ...extra, ...formFieldsValue }));
|
|
175
203
|
// 流程用了;
|
|
176
|
-
return
|
|
204
|
+
return formFieldsValue;
|
|
177
205
|
}
|
|
178
206
|
else {
|
|
179
207
|
setErrors(errorObj);
|
|
@@ -188,62 +216,14 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
188
216
|
const r = await submitPromiseCache.current;
|
|
189
217
|
submitPromiseCache.current = null;
|
|
190
218
|
return r;
|
|
191
|
-
}, [
|
|
192
|
-
|
|
193
|
-
eventsRef,
|
|
194
|
-
formItemMapKey,
|
|
195
|
-
formType,
|
|
196
|
-
formsItemMap,
|
|
197
|
-
isDisabledSubmit,
|
|
198
|
-
validate,
|
|
199
|
-
]);
|
|
200
|
-
const updateFormContextImmediate = useCallback(() => {
|
|
201
|
-
Promise.resolve().then(() => {
|
|
202
|
-
var _a, _b;
|
|
203
|
-
const formData = getFormDataFromItemMap(formsItemMap, formType);
|
|
204
|
-
if (!isObjectEqual(formData, preFormCtxRef.current, true)) {
|
|
205
|
-
(_b = (_a = eventsRef === null || eventsRef === void 0 ? void 0 : eventsRef.current) === null || _a === void 0 ? void 0 : _a.onDataChange) === null || _b === void 0 ? void 0 : _b.call(_a, { data: formData });
|
|
206
|
-
setFormData(formData);
|
|
207
|
-
preFormCtxRef.current = formData;
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
}, [eventsRef, formsItemMap, formType]);
|
|
211
|
-
const updateFormContext = useDebouncedCallback(updateFormContextImmediate,
|
|
212
|
-
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
213
|
-
20, { maxWait: 40, trailing: true });
|
|
214
|
-
const setValueImmediate = useCallback((data, setNull, isImmediate) => {
|
|
219
|
+
}, [_id, eventsRef, formFieldsValue, formType, isDisabledSubmit, validate]);
|
|
220
|
+
const setValue = useCallback((data) => {
|
|
215
221
|
if (typeof data !== 'object' || data === null) {
|
|
216
|
-
console.warn('setValue data need expect a object but got', data);
|
|
222
|
+
console.warn('setValue data need expect a object but got null', data);
|
|
217
223
|
return;
|
|
218
224
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
var _a;
|
|
222
|
-
let items = (_a = formsItemMap.get(name)) !== null && _a !== void 0 ? _a : n;
|
|
223
|
-
if (!Array.isArray(items)) {
|
|
224
|
-
items = [items];
|
|
225
|
-
}
|
|
226
|
-
items.forEach((item) => {
|
|
227
|
-
if (!item.setValue) {
|
|
228
|
-
console.error('表单组件缺少setValue方法:', item);
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
const value = lodashGet(data, name, NOT_EXISTED_VALUE);
|
|
232
|
-
if (value !== NOT_EXISTED_VALUE) {
|
|
233
|
-
item.setValue(value);
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
if (setNull) {
|
|
237
|
-
item.setValue(null);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
});
|
|
242
|
-
isImmediate ? updateFormContextImmediate() : updateFormContext();
|
|
243
|
-
}, [formsItemMap, updateFormContext, updateFormContextImmediate]);
|
|
244
|
-
const setValue = useDebouncedCallback(setValueImmediate,
|
|
245
|
-
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
246
|
-
SET_VALUE_DEBOUNCE_TIMEOUT * 2, { trailing: true });
|
|
225
|
+
setFormData(data);
|
|
226
|
+
}, []);
|
|
247
227
|
const clearValidate = useCallback(() => {
|
|
248
228
|
formsItemMap.forEach((items) => {
|
|
249
229
|
items.forEach((item) => {
|
|
@@ -256,8 +236,10 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
256
236
|
});
|
|
257
237
|
}, [formsItemMap]);
|
|
258
238
|
const [visible, setVisible] = React.useState(false);
|
|
239
|
+
const [isInformContainer, setIsInformContainer] = React.useState(false);
|
|
259
240
|
React.useEffect(() => {
|
|
260
241
|
setVisible(true);
|
|
242
|
+
setIsInformContainer(true);
|
|
261
243
|
}, []);
|
|
262
244
|
useMountEffect(() => {
|
|
263
245
|
logger.debug('formItemMap', formsItemMap);
|
|
@@ -323,6 +305,11 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
323
305
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
324
306
|
[formsItemMap]);
|
|
325
307
|
const { data: formInitValueToSet } = useInitValueFromRemote(datasourceType, dataSourceProfile, fetchedInitialValues);
|
|
308
|
+
const setValueDebounce = useDebouncedCallback(setValue, SET_VALUE_DEBOUNCE_TIMEOUT, {
|
|
309
|
+
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
310
|
+
maxWait: SET_VALUE_DEBOUNCE_TIMEOUT * 2,
|
|
311
|
+
trailing: true,
|
|
312
|
+
});
|
|
326
313
|
useEffect(() => {
|
|
327
314
|
if (initValueLoadingStatus !== 'done' || !fetchedInitialValues)
|
|
328
315
|
return;
|
|
@@ -339,41 +326,28 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
339
326
|
hasSetInitValueRef.current = true;
|
|
340
327
|
return formInitValueToSet;
|
|
341
328
|
});
|
|
342
|
-
|
|
343
|
-
setValue(formInitValueToSet, true);
|
|
329
|
+
setValueDebounce(formInitValueToSet);
|
|
344
330
|
}
|
|
345
|
-
}, [fetchedInitialValues, formInitValueToSet, initValueFetchError, initValueLoadingStatus,
|
|
331
|
+
}, [datasourceType, fetchedInitialValues, formInitValueToSet, initValueFetchError, initValueLoadingStatus, setValueDebounce]);
|
|
346
332
|
React.useEffect(() => {
|
|
347
333
|
var _a, _b;
|
|
348
334
|
// 兼容私有环境,新接口不存在的情况,产品策略完善后移除
|
|
349
|
-
if ((window === null || window === void 0 ? void 0 : window['_isPrivate']) &&
|
|
350
|
-
!((_b = (_a = window === null || window === void 0 ? void 0 : window.app) === null || _a === void 0 ? void 0 : _a.cloud) === null || _b === void 0 ? void 0 : _b.getDataSourceProfileAsync)) {
|
|
335
|
+
if ((window === null || window === void 0 ? void 0 : window['_isPrivate']) && !((_b = (_a = window === null || window === void 0 ? void 0 : window.app) === null || _a === void 0 ? void 0 : _a.cloud) === null || _b === void 0 ? void 0 : _b.getDataSourceProfileAsync)) {
|
|
351
336
|
initDataSourceFieldsWithAuth === null || initDataSourceFieldsWithAuth === void 0 ? void 0 : initDataSourceFieldsWithAuth({ isDataModel });
|
|
352
337
|
return;
|
|
353
338
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
}, [
|
|
358
|
-
authValue,
|
|
359
|
-
isDataModel,
|
|
360
|
-
initDataSourceFieldsWithAuth,
|
|
361
|
-
formsItemMap,
|
|
362
|
-
formItemMapKey,
|
|
363
|
-
]);
|
|
364
|
-
const initedItemMapRef = useRef({});
|
|
365
|
-
const preFormCtxRef = useRef(null);
|
|
366
|
-
const [formData, setFormData] = useState(() => getFormDataFromItemMap(formsItemMap, formType));
|
|
339
|
+
initDataSourceFieldsWithAuth(authValue);
|
|
340
|
+
}, [authValue, isDataModel, initDataSourceFieldsWithAuth, formItemMapKey]);
|
|
367
341
|
const submitParams = useRemoteParamsFromValue({
|
|
368
342
|
dataSourceProfile,
|
|
369
|
-
formData,
|
|
343
|
+
formData: formFieldsValue,
|
|
370
344
|
formType,
|
|
371
345
|
_id,
|
|
372
346
|
});
|
|
373
347
|
useSetWidgetApi(() => {
|
|
374
348
|
const r = {
|
|
375
349
|
formType,
|
|
376
|
-
addFormItem(name, formItem) {
|
|
350
|
+
addFormItem(name, formItem, { initialValue, namePath }) {
|
|
377
351
|
if (isNil(name) || (typeof name === 'string' && name.length === 0)) {
|
|
378
352
|
// name 没设置或为空串的时候不受表单容器控制
|
|
379
353
|
console.warn(`组件 #${formItem === null || formItem === void 0 ? void 0 : formItem.id} 表单key(表单输入类组件 name 属性)没设置或为空串的时候不受表单容器控制`);
|
|
@@ -384,12 +358,30 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
384
358
|
}
|
|
385
359
|
else {
|
|
386
360
|
formsItemMap.set(name, [formItem]);
|
|
361
|
+
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
362
|
+
if (name && (namePath === null || namePath === void 0 ? void 0 : namePath.length) === 1) {
|
|
363
|
+
setFormItemMapList((formItemMapList) => [...formItemMapList, name]);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
// 设置初始值
|
|
367
|
+
// form的初始值>formArr/formObj/formDetail>field
|
|
368
|
+
if (initialValue !== undefined) {
|
|
369
|
+
const _initialValues = deepClone(initialValues);
|
|
370
|
+
const value = lodashGet(_initialValues, namePath, NOT_EXISTED_VALUE);
|
|
371
|
+
if (value === NOT_EXISTED_VALUE) {
|
|
372
|
+
setFieldInitValueCache((fieldInitValueCache) => {
|
|
373
|
+
const _fieldInitValueCache = deepClone(fieldInitValueCache);
|
|
374
|
+
lodashSet(_fieldInitValueCache, namePath, initialValue);
|
|
375
|
+
return _fieldInitValueCache;
|
|
376
|
+
});
|
|
377
|
+
}
|
|
387
378
|
}
|
|
388
379
|
return () => {
|
|
389
380
|
const items = formsItemMap.get(name);
|
|
390
381
|
const removedArr = items.filter((item) => item !== formItem);
|
|
391
382
|
if (removedArr.length <= 0) {
|
|
392
383
|
formsItemMap.delete(name);
|
|
384
|
+
setFormItemMapList((formItemMapList) => formItemMapList.filter((item) => item !== name));
|
|
393
385
|
}
|
|
394
386
|
else {
|
|
395
387
|
formsItemMap.set(name, removedArr);
|
|
@@ -397,16 +389,25 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
397
389
|
};
|
|
398
390
|
},
|
|
399
391
|
submitParams,
|
|
400
|
-
setValue,
|
|
392
|
+
setValue(value, opts = { notMerge: false }) {
|
|
393
|
+
// notMerge 默认false,表示与之前的表单值合并
|
|
394
|
+
if (opts.notMerge) {
|
|
395
|
+
setValueDebounce(value);
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
const _formFieldsValue = deepClone(formFieldsValue);
|
|
399
|
+
setValueDebounce({ ..._formFieldsValue, ...value });
|
|
400
|
+
}
|
|
401
|
+
},
|
|
401
402
|
reset() {
|
|
402
|
-
|
|
403
|
+
setValueDebounce(initialValues);
|
|
403
404
|
},
|
|
404
405
|
clearValue({ isImmediate = false } = {}) {
|
|
405
406
|
if (isImmediate) {
|
|
406
|
-
|
|
407
|
+
setValue({});
|
|
407
408
|
}
|
|
408
409
|
else {
|
|
409
|
-
|
|
410
|
+
setValueDebounce({});
|
|
410
411
|
}
|
|
411
412
|
},
|
|
412
413
|
async validate() {
|
|
@@ -434,9 +435,8 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
434
435
|
authValue,
|
|
435
436
|
layout,
|
|
436
437
|
dataSourceName,
|
|
437
|
-
value:
|
|
438
|
+
value: formFieldsValue,
|
|
438
439
|
remoteValue: fetchedInitialValues,
|
|
439
|
-
updateFormContext,
|
|
440
440
|
dataSourceProfile,
|
|
441
441
|
errors,
|
|
442
442
|
clearValidate,
|
|
@@ -447,25 +447,22 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
447
447
|
isDisabledSubmit,
|
|
448
448
|
disableSubmit,
|
|
449
449
|
enableSubmit,
|
|
450
|
-
|
|
450
|
+
fieldInitValueCache,
|
|
451
451
|
};
|
|
452
452
|
return r;
|
|
453
453
|
}, [
|
|
454
454
|
formType,
|
|
455
455
|
submitParams,
|
|
456
456
|
setValue,
|
|
457
|
+
setValueDebounce,
|
|
457
458
|
initialValues,
|
|
458
459
|
authValue,
|
|
459
460
|
layout,
|
|
460
461
|
dataSourceName,
|
|
461
|
-
|
|
462
|
+
formFieldsValue,
|
|
462
463
|
fetchedInitialValues,
|
|
463
|
-
updateFormContext,
|
|
464
464
|
dataSourceProfile,
|
|
465
465
|
errors,
|
|
466
|
-
formsItemMap,
|
|
467
|
-
submit,
|
|
468
|
-
validate,
|
|
469
466
|
clearValidate,
|
|
470
467
|
datasourceType,
|
|
471
468
|
methodCreate,
|
|
@@ -474,8 +471,11 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
474
471
|
isDisabledSubmit,
|
|
475
472
|
disableSubmit,
|
|
476
473
|
enableSubmit,
|
|
474
|
+
fieldInitValueCache,
|
|
475
|
+
formsItemMap,
|
|
476
|
+
validate,
|
|
477
477
|
eventsRef,
|
|
478
|
-
|
|
478
|
+
submit,
|
|
479
479
|
], ref);
|
|
480
480
|
useUnmountEffect(() => {
|
|
481
481
|
if (typeof ref === 'function') {
|
|
@@ -485,86 +485,10 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
485
485
|
ref.current = null;
|
|
486
486
|
}
|
|
487
487
|
});
|
|
488
|
-
const setInitValueImmediate = useCallback(() => {
|
|
489
|
-
// 获取子表单初始值
|
|
490
|
-
const formDetailInitValue = {};
|
|
491
|
-
for (const [name, formItems] of formsItemMap.entries()) {
|
|
492
|
-
formItems.forEach((formItem) => {
|
|
493
|
-
var _a, _b;
|
|
494
|
-
if (((_b = (_a = formItem === null || formItem === void 0 ? void 0 : formItem.getConfig) === null || _a === void 0 ? void 0 : _a.call(formItem)) === null || _b === void 0 ? void 0 : _b.componentType) === 'formdetail') {
|
|
495
|
-
formDetailInitValue[name] = formItem === null || formItem === void 0 ? void 0 : formItem.value;
|
|
496
|
-
}
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
const entires = [...formsItemMap.entries()];
|
|
500
|
-
unstable_batchedUpdates(() => {
|
|
501
|
-
for (const [name, formItems] of entires) {
|
|
502
|
-
// 合并子表单初始值与表单初始值
|
|
503
|
-
const formItem = formItems;
|
|
504
|
-
const initValues = { ...formDetailInitValue, ...formInitValueToSet };
|
|
505
|
-
const value = lodashGet(initValues, name);
|
|
506
|
-
if (initedItemMapRef.current[name] !== true && value !== undefined) {
|
|
507
|
-
formItems.forEach((item) => {
|
|
508
|
-
var _a;
|
|
509
|
-
logger.debug(`set VALUE ${name}`, value, formItem);
|
|
510
|
-
(_a = item.setValue) === null || _a === void 0 ? void 0 : _a.call(item, value);
|
|
511
|
-
});
|
|
512
|
-
initedItemMapRef.current[name] = true;
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
|
-
updateFormContext();
|
|
517
|
-
}, [formInitValueToSet, formsItemMap, updateFormContext]);
|
|
518
|
-
const setInitValue = useDebouncedCallback(setInitValueImmediate, SET_VALUE_DEBOUNCE_TIMEOUT, {
|
|
519
|
-
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
520
|
-
maxWait: SET_VALUE_DEBOUNCE_TIMEOUT * 2,
|
|
521
|
-
trailing: true,
|
|
522
|
-
});
|
|
523
|
-
const lastInitValueRef = useRef(null);
|
|
524
|
-
React.useEffect(() => {
|
|
525
|
-
if (isObjectEqual(lastInitValueRef.current, initialValues) &&
|
|
526
|
-
isObjectEqual(formItemMapKeyRef.current, formItemMapKey)) {
|
|
527
|
-
return;
|
|
528
|
-
}
|
|
529
|
-
// 单向 Form向下设置值
|
|
530
|
-
let setValueReady = false;
|
|
531
|
-
const timeout = 30;
|
|
532
|
-
let id;
|
|
533
|
-
const setValueUntilReady = () => {
|
|
534
|
-
setValueReady = [...formsItemMap.values()].every((items) => items.every((item) => !!item.setValue));
|
|
535
|
-
if (id) {
|
|
536
|
-
clearTimeout(id);
|
|
537
|
-
id = null;
|
|
538
|
-
}
|
|
539
|
-
if (!setValueReady) {
|
|
540
|
-
// eslint-disable-next-line rulesdir/no-timer
|
|
541
|
-
id = setTimeout(() => {
|
|
542
|
-
setValueUntilReady();
|
|
543
|
-
}, timeout);
|
|
544
|
-
return;
|
|
545
|
-
}
|
|
546
|
-
/* formInitValueToSet 被初始化后会调用setValue
|
|
547
|
-
此时form items都有了,但是setInitValue 里面batch update 之后还是会出现form detail内部有时设置不上值(下断点或电脑卡就可以)
|
|
548
|
-
不batch update form item 多了会非常非常卡,所以搞两下
|
|
549
|
-
|
|
550
|
-
https://andon.woa.com/ticket/detail/?id=11607503&sign=e9f203927d29c0007a797039a1471f7d
|
|
551
|
-
*/
|
|
552
|
-
setInitValueImmediate();
|
|
553
|
-
Promise.resolve().then(setInitValue);
|
|
554
|
-
};
|
|
555
|
-
setValueUntilReady();
|
|
556
|
-
lastInitValueRef.current = initialValues;
|
|
557
|
-
formItemMapKeyRef.current = formItemMapKey;
|
|
558
|
-
return () => {
|
|
559
|
-
if (id) {
|
|
560
|
-
clearTimeout(id);
|
|
561
|
-
}
|
|
562
|
-
};
|
|
563
|
-
});
|
|
564
488
|
useLayoutEffect(() => {
|
|
565
489
|
// 兼容流程
|
|
566
490
|
if ($node) {
|
|
567
|
-
$node.setValue = setValue;
|
|
491
|
+
$node.setValue = ref === null || ref === void 0 ? void 0 : ref.setValue;
|
|
568
492
|
$node.submit = submit;
|
|
569
493
|
$node.formItems = '为了兼容不报错';
|
|
570
494
|
return () => {
|
|
@@ -573,16 +497,43 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
573
497
|
$node.formItems = undefined;
|
|
574
498
|
};
|
|
575
499
|
}
|
|
576
|
-
}, [$node, setValue, submit]);
|
|
500
|
+
}, [$node, ref === null || ref === void 0 ? void 0 : ref.setValue, submit]);
|
|
577
501
|
const labelPosition = useMemo(() => {
|
|
578
502
|
return `${layout}-${labelAlign}`;
|
|
579
503
|
}, [layout, labelAlign]);
|
|
504
|
+
const getFieldValue = useCallback(({ namePath, initialValue }) => {
|
|
505
|
+
const value = lodashGet(formFieldsValue, namePath, NOT_EXISTED_VALUE);
|
|
506
|
+
if (value !== NOT_EXISTED_VALUE) {
|
|
507
|
+
return value;
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
// 设置初始值,兼容表单项变量绑定场景
|
|
511
|
+
// form的初始值>formArr/formObj/formDetail>field
|
|
512
|
+
if (initialValue !== undefined) {
|
|
513
|
+
return initialValue;
|
|
514
|
+
}
|
|
515
|
+
return null;
|
|
516
|
+
}
|
|
517
|
+
}, [formFieldsValue]);
|
|
518
|
+
const setFieldValue = useCallback(({ namePath, value }) => {
|
|
519
|
+
const _formData = deepClone(formData);
|
|
520
|
+
const _value = lodashGet(_formData, namePath, NOT_EXISTED_VALUE);
|
|
521
|
+
if (isObjectEqual(_value, value)) {
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
lodashSet(_formData, namePath, value);
|
|
525
|
+
setValue(_formData);
|
|
526
|
+
}, [formData, setValue]);
|
|
580
527
|
if (initValueLoadingStatus === 'hidden') {
|
|
581
528
|
return null;
|
|
582
529
|
}
|
|
583
|
-
if (initValueLoadingStatus === 'loading' && !fetchedInitialValues) {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
530
|
+
// if (initValueLoadingStatus === 'loading' && !fetchedInitialValues) {
|
|
531
|
+
// return (
|
|
532
|
+
// <ConfigProvider classPrefix="wedatea2td">
|
|
533
|
+
// <StatusTip status="loading" loadingText="数据加载中..." />
|
|
534
|
+
// </ConfigProvider>
|
|
535
|
+
// );
|
|
536
|
+
// }
|
|
537
|
+
return (_jsx(FormWidgetProvider, { "$widget": $widget, children: _jsx(FormLayoutProvider, { layout: layout, children: _jsx(FormTypeProvider, { formType: formType, children: _jsx(FormFieldProvider, { setFieldValue: setFieldValue, isInformContainer: isInformContainer, getFieldValue: getFieldValue, children: _jsx(FormUi, { layout: layout, className: cls, style: style, id: id, lgWidth: lgWidth, labelPosition: labelPosition, children: initValueFetchError ? (_jsx(EmptyContent, { emptyText: '数据加载失败', errorObj: initValueFetchError, icon: 'error', isH5: isH5 })) : (visible && contentSlot) }) }) }) }) }));
|
|
587
538
|
});
|
|
588
539
|
export default React.memo(WdForm);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import type { WdFormItemProps } from '../../../configs/type-utils/type-form';
|
|
3
3
|
/**
|
|
4
4
|
* 表单项包裹,包括标题、文本提示、校验
|
|
5
5
|
*/
|
|
6
|
-
export declare
|
|
6
|
+
export declare const WdFormItem: React.NamedExoticComponent<WdFormItemProps>;
|
|
7
7
|
export type { WdFormItemProps };
|