@cloudbase/weda-ui 3.19.0 → 3.20.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/dist/configs/components/wd-form.d.ts +2 -2
- package/dist/configs/components/wd-form.js +2 -3
- 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 +1 -1
- package/dist/web/components/form-rich-text/index.js +6 -2
- 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/form-utils.d.ts +1 -0
- package/dist/web/components/wd-form/form-utils.js +32 -0
- package/dist/web/components/wd-form/index.d.ts +4 -4
- package/dist/web/components/wd-form/index.js +137 -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 +57 -197
- package/dist/web/components/wd-input/wd-input.js +1 -1
- package/dist/web/components/wd-input-number/wd-input-number.js +40 -2
- 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-table/components/Table/index.js +14 -9
- package/dist/web/components/wd-table/utils/index.d.ts +0 -1
- package/dist/web/components/wd-table/utils/index.js +1 -1
- 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,38 @@
|
|
|
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';
|
|
23
22
|
import '../style';
|
|
24
|
-
import { getErrorObjectFromValidateResult
|
|
25
|
-
import { ConfigProvider, StatusTip } from 'tea-component';
|
|
23
|
+
import { getErrorObjectFromValidateResult } from './form-utils';
|
|
26
24
|
import { isNil } from '../../utils/lodash';
|
|
27
25
|
import { FormTypeProvider } from './contexts/form-type-context';
|
|
28
26
|
import { FormLayoutProvider } from './contexts/form-layout-context';
|
|
29
27
|
import { FormWidgetProvider } from './contexts/form-widget-context';
|
|
30
|
-
import
|
|
28
|
+
import { FormFieldProvider } from './contexts/form-field-context';
|
|
31
29
|
import { useSyncValue } from '../../utils/hooks/useSyncValue';
|
|
32
|
-
|
|
33
|
-
// eslint-disable-next-line rulesdir/no-timer
|
|
34
|
-
setTimeout(resolve, ms);
|
|
35
|
-
});
|
|
30
|
+
import useDebouncedCallback from '../../utils/hooks/use-debounced-callback';
|
|
36
31
|
const SET_VALUE_DEBOUNCE_TIMEOUT = 250;
|
|
37
32
|
const logger = debug('wd-form');
|
|
38
33
|
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',
|
|
34
|
+
var _a, _b, _c, _d;
|
|
35
|
+
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
36
|
// 兼容流程setValue调用,其他地方别用
|
|
42
37
|
$node, $widget, } = props;
|
|
43
38
|
const formsItemMap = useMap([]);
|
|
@@ -47,7 +42,8 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
47
42
|
* 所以要用它作useEffect deps的时候用下面这个string
|
|
48
43
|
* */
|
|
49
44
|
const formItemMapKey = [...formsItemMap.keys()].sort().join(',');
|
|
50
|
-
|
|
45
|
+
// 用于存储表单下的一级节点
|
|
46
|
+
const [formItemMapList, setFormItemMapList] = useState([]);
|
|
51
47
|
const platform = usePlatform();
|
|
52
48
|
const isH5 = platform === 'h5';
|
|
53
49
|
const contentSlot = useMemo(() => contentSlotEl, [contentSlotEl]);
|
|
@@ -70,8 +66,42 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
70
66
|
}, [setIsDisabledSubmit]);
|
|
71
67
|
const hasSetInitValueRef = useRef(false);
|
|
72
68
|
const { ready } = useWedaAppContext();
|
|
73
|
-
|
|
69
|
+
// 缓存表单项的初始值
|
|
70
|
+
const [fieldInitValueCache, setFieldInitValueCache] = useState((_a = deepClone(_initialValues)) !== null && _a !== void 0 ? _a : emptyObject);
|
|
71
|
+
// 表单初始值
|
|
72
|
+
const [initialValues, setInitialValues] = useState((_b = deepClone(_initialValues)) !== null && _b !== void 0 ? _b : emptyObject);
|
|
74
73
|
const [propsValue] = useSyncValue(props.value);
|
|
74
|
+
// 表单值
|
|
75
|
+
const [formData, setFormData] = useState((_c = deepClone(_initialValues)) !== null && _c !== void 0 ? _c : emptyObject);
|
|
76
|
+
// 转换后表单值,仅保留已挂载表单项的值
|
|
77
|
+
const [formFieldsValue, setFormFieldsValue] = useState((_d = deepClone(_initialValues)) !== null && _d !== void 0 ? _d : emptyObject);
|
|
78
|
+
useDebouncedEffect(() => {
|
|
79
|
+
var _a, _b;
|
|
80
|
+
// 表单容器上挂载的表单项的值,没有则置空
|
|
81
|
+
const convertFormData = (formData, setNull = false) => {
|
|
82
|
+
const data = {};
|
|
83
|
+
formItemMapList.forEach((i) => {
|
|
84
|
+
const namePath = i;
|
|
85
|
+
const value = lodashGet(formData, namePath, NOT_EXISTED_VALUE);
|
|
86
|
+
// 表单容器内不包含的表单项,不赋值
|
|
87
|
+
if (value !== NOT_EXISTED_VALUE) {
|
|
88
|
+
lodashSet(data, namePath, value);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
if (setNull) {
|
|
92
|
+
lodashSet(data, namePath, null);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
const _fieldInitValueCache = deepClone(fieldInitValueCache);
|
|
97
|
+
return Object.assign(_fieldInitValueCache, data);
|
|
98
|
+
};
|
|
99
|
+
const _data = convertFormData(formData);
|
|
100
|
+
setFormFieldsValue(_data);
|
|
101
|
+
(_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 });
|
|
102
|
+
}, [formData, fieldInitValueCache],
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
104
|
+
SET_VALUE_DEBOUNCE_TIMEOUT);
|
|
75
105
|
const eventsRef = useSyncedRef(props.events);
|
|
76
106
|
const validate = useCallback(async () => {
|
|
77
107
|
const validatePromise = [];
|
|
@@ -115,6 +145,7 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
115
145
|
return errObj;
|
|
116
146
|
}, [formsItemMap]);
|
|
117
147
|
const [errors, setErrors] = useState(undefined);
|
|
148
|
+
// 用于存储关联关系查询字段
|
|
118
149
|
const allSelectFields = useMemo(() => {
|
|
119
150
|
if (!ready) {
|
|
120
151
|
return null;
|
|
@@ -163,17 +194,13 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
163
194
|
return;
|
|
164
195
|
const run = async () => {
|
|
165
196
|
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
197
|
const errorObj = await validate();
|
|
169
198
|
if (Object.keys(errorObj !== null && errorObj !== void 0 ? errorObj : {}).length === 0) {
|
|
170
199
|
validateSuccess({ errors: {} });
|
|
171
|
-
logger.debug('formItemMapKey', formItemMapKey);
|
|
172
|
-
const formData = getFormDataFromItemMap(formsItemMap, formType);
|
|
173
200
|
const extra = ['read', 'edit'].includes(formType) && _id ? { _id } : {};
|
|
174
|
-
submit && submit(deepClone({ ...extra, ...
|
|
201
|
+
submit && submit(deepClone({ ...extra, ...formFieldsValue }));
|
|
175
202
|
// 流程用了;
|
|
176
|
-
return
|
|
203
|
+
return formFieldsValue;
|
|
177
204
|
}
|
|
178
205
|
else {
|
|
179
206
|
setErrors(errorObj);
|
|
@@ -188,62 +215,14 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
188
215
|
const r = await submitPromiseCache.current;
|
|
189
216
|
submitPromiseCache.current = null;
|
|
190
217
|
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) => {
|
|
218
|
+
}, [_id, eventsRef, formFieldsValue, formType, isDisabledSubmit, validate]);
|
|
219
|
+
const setValue = useCallback((data) => {
|
|
215
220
|
if (typeof data !== 'object' || data === null) {
|
|
216
|
-
console.warn('setValue data need expect a object but got', data);
|
|
221
|
+
console.warn('setValue data need expect a object but got null', data);
|
|
217
222
|
return;
|
|
218
223
|
}
|
|
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 });
|
|
224
|
+
setFormData(data);
|
|
225
|
+
}, []);
|
|
247
226
|
const clearValidate = useCallback(() => {
|
|
248
227
|
formsItemMap.forEach((items) => {
|
|
249
228
|
items.forEach((item) => {
|
|
@@ -256,8 +235,10 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
256
235
|
});
|
|
257
236
|
}, [formsItemMap]);
|
|
258
237
|
const [visible, setVisible] = React.useState(false);
|
|
238
|
+
const [isInformContainer, setIsInformContainer] = React.useState(false);
|
|
259
239
|
React.useEffect(() => {
|
|
260
240
|
setVisible(true);
|
|
241
|
+
setIsInformContainer(true);
|
|
261
242
|
}, []);
|
|
262
243
|
useMountEffect(() => {
|
|
263
244
|
logger.debug('formItemMap', formsItemMap);
|
|
@@ -323,6 +304,11 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
323
304
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
324
305
|
[formsItemMap]);
|
|
325
306
|
const { data: formInitValueToSet } = useInitValueFromRemote(datasourceType, dataSourceProfile, fetchedInitialValues);
|
|
307
|
+
const setValueDebounce = useDebouncedCallback(setValue, SET_VALUE_DEBOUNCE_TIMEOUT, {
|
|
308
|
+
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
309
|
+
maxWait: SET_VALUE_DEBOUNCE_TIMEOUT * 2,
|
|
310
|
+
trailing: true,
|
|
311
|
+
});
|
|
326
312
|
useEffect(() => {
|
|
327
313
|
if (initValueLoadingStatus !== 'done' || !fetchedInitialValues)
|
|
328
314
|
return;
|
|
@@ -339,41 +325,28 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
339
325
|
hasSetInitValueRef.current = true;
|
|
340
326
|
return formInitValueToSet;
|
|
341
327
|
});
|
|
342
|
-
|
|
343
|
-
setValue(formInitValueToSet, true);
|
|
328
|
+
setValueDebounce(formInitValueToSet);
|
|
344
329
|
}
|
|
345
|
-
}, [fetchedInitialValues, formInitValueToSet, initValueFetchError, initValueLoadingStatus,
|
|
330
|
+
}, [datasourceType, fetchedInitialValues, formInitValueToSet, initValueFetchError, initValueLoadingStatus, setValueDebounce]);
|
|
346
331
|
React.useEffect(() => {
|
|
347
332
|
var _a, _b;
|
|
348
333
|
// 兼容私有环境,新接口不存在的情况,产品策略完善后移除
|
|
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)) {
|
|
334
|
+
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
335
|
initDataSourceFieldsWithAuth === null || initDataSourceFieldsWithAuth === void 0 ? void 0 : initDataSourceFieldsWithAuth({ isDataModel });
|
|
352
336
|
return;
|
|
353
337
|
}
|
|
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));
|
|
338
|
+
initDataSourceFieldsWithAuth(authValue);
|
|
339
|
+
}, [authValue, isDataModel, initDataSourceFieldsWithAuth, formItemMapKey]);
|
|
367
340
|
const submitParams = useRemoteParamsFromValue({
|
|
368
341
|
dataSourceProfile,
|
|
369
|
-
formData,
|
|
342
|
+
formData: formFieldsValue,
|
|
370
343
|
formType,
|
|
371
344
|
_id,
|
|
372
345
|
});
|
|
373
346
|
useSetWidgetApi(() => {
|
|
374
347
|
const r = {
|
|
375
348
|
formType,
|
|
376
|
-
addFormItem(name, formItem) {
|
|
349
|
+
addFormItem(name, formItem, { initialValue, namePath }) {
|
|
377
350
|
if (isNil(name) || (typeof name === 'string' && name.length === 0)) {
|
|
378
351
|
// name 没设置或为空串的时候不受表单容器控制
|
|
379
352
|
console.warn(`组件 #${formItem === null || formItem === void 0 ? void 0 : formItem.id} 表单key(表单输入类组件 name 属性)没设置或为空串的时候不受表单容器控制`);
|
|
@@ -384,12 +357,30 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
384
357
|
}
|
|
385
358
|
else {
|
|
386
359
|
formsItemMap.set(name, [formItem]);
|
|
360
|
+
// eslint-disable-next-line @typescript-eslint/no-magic-numbers
|
|
361
|
+
if (name && (namePath === null || namePath === void 0 ? void 0 : namePath.length) === 1) {
|
|
362
|
+
setFormItemMapList((formItemMapList) => [...formItemMapList, name]);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// 设置初始值
|
|
366
|
+
// form的初始值>formArr/formObj/formDetail>field
|
|
367
|
+
if (initialValue !== undefined) {
|
|
368
|
+
const _initialValues = deepClone(initialValues);
|
|
369
|
+
const value = lodashGet(_initialValues, namePath, NOT_EXISTED_VALUE);
|
|
370
|
+
if (value === NOT_EXISTED_VALUE) {
|
|
371
|
+
setFieldInitValueCache((fieldInitValueCache) => {
|
|
372
|
+
const _fieldInitValueCache = deepClone(fieldInitValueCache);
|
|
373
|
+
lodashSet(_fieldInitValueCache, namePath, initialValue);
|
|
374
|
+
return _fieldInitValueCache;
|
|
375
|
+
});
|
|
376
|
+
}
|
|
387
377
|
}
|
|
388
378
|
return () => {
|
|
389
379
|
const items = formsItemMap.get(name);
|
|
390
380
|
const removedArr = items.filter((item) => item !== formItem);
|
|
391
381
|
if (removedArr.length <= 0) {
|
|
392
382
|
formsItemMap.delete(name);
|
|
383
|
+
setFormItemMapList((formItemMapList) => formItemMapList.filter((item) => item !== name));
|
|
393
384
|
}
|
|
394
385
|
else {
|
|
395
386
|
formsItemMap.set(name, removedArr);
|
|
@@ -397,16 +388,25 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
397
388
|
};
|
|
398
389
|
},
|
|
399
390
|
submitParams,
|
|
400
|
-
setValue,
|
|
391
|
+
setValue(value, opts = { notMerge: false }) {
|
|
392
|
+
// notMerge 默认false,表示与之前的表单值合并
|
|
393
|
+
if (opts.notMerge) {
|
|
394
|
+
setValueDebounce(value);
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
const _formFieldsValue = deepClone(formFieldsValue);
|
|
398
|
+
setValueDebounce({ ..._formFieldsValue, ...value });
|
|
399
|
+
}
|
|
400
|
+
},
|
|
401
401
|
reset() {
|
|
402
|
-
|
|
402
|
+
setValueDebounce(initialValues);
|
|
403
403
|
},
|
|
404
404
|
clearValue({ isImmediate = false } = {}) {
|
|
405
405
|
if (isImmediate) {
|
|
406
|
-
|
|
406
|
+
setValue({});
|
|
407
407
|
}
|
|
408
408
|
else {
|
|
409
|
-
|
|
409
|
+
setValueDebounce({});
|
|
410
410
|
}
|
|
411
411
|
},
|
|
412
412
|
async validate() {
|
|
@@ -434,9 +434,8 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
434
434
|
authValue,
|
|
435
435
|
layout,
|
|
436
436
|
dataSourceName,
|
|
437
|
-
value:
|
|
437
|
+
value: formFieldsValue,
|
|
438
438
|
remoteValue: fetchedInitialValues,
|
|
439
|
-
updateFormContext,
|
|
440
439
|
dataSourceProfile,
|
|
441
440
|
errors,
|
|
442
441
|
clearValidate,
|
|
@@ -447,25 +446,22 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
447
446
|
isDisabledSubmit,
|
|
448
447
|
disableSubmit,
|
|
449
448
|
enableSubmit,
|
|
450
|
-
|
|
449
|
+
fieldInitValueCache,
|
|
451
450
|
};
|
|
452
451
|
return r;
|
|
453
452
|
}, [
|
|
454
453
|
formType,
|
|
455
454
|
submitParams,
|
|
456
455
|
setValue,
|
|
456
|
+
setValueDebounce,
|
|
457
457
|
initialValues,
|
|
458
458
|
authValue,
|
|
459
459
|
layout,
|
|
460
460
|
dataSourceName,
|
|
461
|
-
|
|
461
|
+
formFieldsValue,
|
|
462
462
|
fetchedInitialValues,
|
|
463
|
-
updateFormContext,
|
|
464
463
|
dataSourceProfile,
|
|
465
464
|
errors,
|
|
466
|
-
formsItemMap,
|
|
467
|
-
submit,
|
|
468
|
-
validate,
|
|
469
465
|
clearValidate,
|
|
470
466
|
datasourceType,
|
|
471
467
|
methodCreate,
|
|
@@ -474,8 +470,11 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
474
470
|
isDisabledSubmit,
|
|
475
471
|
disableSubmit,
|
|
476
472
|
enableSubmit,
|
|
473
|
+
fieldInitValueCache,
|
|
474
|
+
formsItemMap,
|
|
475
|
+
validate,
|
|
477
476
|
eventsRef,
|
|
478
|
-
|
|
477
|
+
submit,
|
|
479
478
|
], ref);
|
|
480
479
|
useUnmountEffect(() => {
|
|
481
480
|
if (typeof ref === 'function') {
|
|
@@ -485,86 +484,10 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
485
484
|
ref.current = null;
|
|
486
485
|
}
|
|
487
486
|
});
|
|
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
487
|
useLayoutEffect(() => {
|
|
565
488
|
// 兼容流程
|
|
566
489
|
if ($node) {
|
|
567
|
-
$node.setValue = setValue;
|
|
490
|
+
$node.setValue = ref === null || ref === void 0 ? void 0 : ref.setValue;
|
|
568
491
|
$node.submit = submit;
|
|
569
492
|
$node.formItems = '为了兼容不报错';
|
|
570
493
|
return () => {
|
|
@@ -573,16 +496,39 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
|
|
|
573
496
|
$node.formItems = undefined;
|
|
574
497
|
};
|
|
575
498
|
}
|
|
576
|
-
}, [$node, setValue, submit]);
|
|
499
|
+
}, [$node, ref === null || ref === void 0 ? void 0 : ref.setValue, submit]);
|
|
577
500
|
const labelPosition = useMemo(() => {
|
|
578
501
|
return `${layout}-${labelAlign}`;
|
|
579
502
|
}, [layout, labelAlign]);
|
|
503
|
+
const getFieldValue = useCallback(({ namePath, initialValue }) => {
|
|
504
|
+
const value = lodashGet(formFieldsValue, namePath, NOT_EXISTED_VALUE);
|
|
505
|
+
if (value !== NOT_EXISTED_VALUE) {
|
|
506
|
+
return value;
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
// 设置初始值,兼容表单项变量绑定场景
|
|
510
|
+
// form的初始值>formArr/formObj/formDetail>field
|
|
511
|
+
if (initialValue !== undefined) {
|
|
512
|
+
return initialValue;
|
|
513
|
+
}
|
|
514
|
+
return null;
|
|
515
|
+
}
|
|
516
|
+
}, [formFieldsValue]);
|
|
517
|
+
const setFieldValue = useCallback(({ namePath, value }) => {
|
|
518
|
+
const _formData = deepClone(formData);
|
|
519
|
+
lodashSet(_formData, namePath, value);
|
|
520
|
+
setValue(_formData);
|
|
521
|
+
}, [formData, setValue]);
|
|
580
522
|
if (initValueLoadingStatus === 'hidden') {
|
|
581
523
|
return null;
|
|
582
524
|
}
|
|
583
|
-
if (initValueLoadingStatus === 'loading' && !fetchedInitialValues) {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
525
|
+
// if (initValueLoadingStatus === 'loading' && !fetchedInitialValues) {
|
|
526
|
+
// return (
|
|
527
|
+
// <ConfigProvider classPrefix="wedatea2td">
|
|
528
|
+
// <StatusTip status="loading" loadingText="数据加载中..." />
|
|
529
|
+
// </ConfigProvider>
|
|
530
|
+
// );
|
|
531
|
+
// }
|
|
532
|
+
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
533
|
});
|
|
588
534
|
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 };
|