fix: should not display currentRecord in creation form block (#2814)
* fix: should not display currentRecord in creation form block * fix: avoid crashing * fix: fix T-2212
This commit is contained in:
parent
bb5093cfc2
commit
e5cca1dcb1
@ -2,8 +2,9 @@ import { Field } from '@formily/core';
|
|||||||
import { useField, useFieldSchema } from '@formily/react';
|
import { useField, useFieldSchema } from '@formily/react';
|
||||||
import { reaction } from '@formily/reactive';
|
import { reaction } from '@formily/reactive';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useRecord, useRecordIndex } from '../../../../../src/record-provider';
|
import { useRecord, useRecordIndex } from '../../../../../src/record-provider';
|
||||||
|
import { useFormBlockType } from '../../../../block-provider/FormBlockProvider';
|
||||||
import { useCollection } from '../../../../collection-manager';
|
import { useCollection } from '../../../../collection-manager';
|
||||||
import { useFlag } from '../../../../flag-provider';
|
import { useFlag } from '../../../../flag-provider';
|
||||||
import { DEBOUNCE_WAIT, useLocalVariables, useVariables } from '../../../../variables';
|
import { DEBOUNCE_WAIT, useLocalVariables, useVariables } from '../../../../variables';
|
||||||
@ -27,9 +28,7 @@ const useParseDefaultValue = () => {
|
|||||||
const { getField } = useCollection();
|
const { getField } = useCollection();
|
||||||
const { isSpecialCase, setDefaultValue } = useSpecialCase();
|
const { isSpecialCase, setDefaultValue } = useSpecialCase();
|
||||||
const index = useRecordIndex();
|
const index = useRecordIndex();
|
||||||
|
const { type: formBlockType } = useFormBlockType();
|
||||||
// 需要保存 record 的初始值,因为设置默认值的时候 record 会被修改,导致初始值丢失
|
|
||||||
const recordRef = useRef(_.omit(record, '__parent'));
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
@ -37,8 +36,8 @@ const useParseDefaultValue = () => {
|
|||||||
isInSetDefaultValueDialog ||
|
isInSetDefaultValueDialog ||
|
||||||
isInFormDataTemplate ||
|
isInFormDataTemplate ||
|
||||||
isSubMode(fieldSchema) ||
|
isSubMode(fieldSchema) ||
|
||||||
// 根据 record 是否为空,判断当前是否是新建状态,编辑状态下不需要设置默认值,否则会覆盖用户输入的值,只有新建状态下才需要设置默认值
|
// 编辑状态下不需要设置默认值,否则会覆盖用户输入的值,只有新建状态下才需要设置默认值
|
||||||
(!_.isEmpty(recordRef.current) && isFromDatabase(record) && !isInAssignFieldValues)
|
(formBlockType === 'update' && isFromDatabase(record) && !isInAssignFieldValues)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -99,7 +98,16 @@ const useParseDefaultValue = () => {
|
|||||||
if (variableValue) {
|
if (variableValue) {
|
||||||
// 实现联动的效果,当依赖的变量变化时(如 `$nForm` 变量),重新解析默认值
|
// 实现联动的效果,当依赖的变量变化时(如 `$nForm` 变量),重新解析默认值
|
||||||
const dispose = reaction(() => {
|
const dispose = reaction(() => {
|
||||||
return _.get({ [variableName]: variableValue?.ctx }, getPath(fieldSchema.default));
|
const obj = { [variableName]: variableValue?.ctx };
|
||||||
|
const path = getPath(fieldSchema.default);
|
||||||
|
|
||||||
|
// fix https://nocobase.height.app/T-2212
|
||||||
|
if (_.get(obj, path) === undefined) {
|
||||||
|
// 返回一个随机值,确保能触发 run 函数
|
||||||
|
return Math.random();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _.get(obj, path);
|
||||||
}, run);
|
}, run);
|
||||||
|
|
||||||
return dispose;
|
return dispose;
|
||||||
|
@ -70,6 +70,10 @@ export const linkageMergeAction = async ({
|
|||||||
) {
|
) {
|
||||||
let result = null;
|
let result = null;
|
||||||
if (value?.mode === 'express') {
|
if (value?.mode === 'express') {
|
||||||
|
if ((value.value || value.result) == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const scope = cloneDeep(values);
|
const scope = cloneDeep(values);
|
||||||
|
|
||||||
// 1. 解析如 `{{$user.name}}` 之类的变量
|
// 1. 解析如 `{{$user.name}}` 之类的变量
|
||||||
@ -113,6 +117,10 @@ async function replaceVariables(
|
|||||||
const store = {};
|
const store = {};
|
||||||
const scope = {};
|
const scope = {};
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const waitForParsing = value.match(REGEX_OF_VARIABLE)?.map(async (item) => {
|
const waitForParsing = value.match(REGEX_OF_VARIABLE)?.map(async (item) => {
|
||||||
const result = await variables.parseVariable(item, localVariables);
|
const result = await variables.parseVariable(item, localVariables);
|
||||||
|
|
||||||
|
@ -22,6 +22,10 @@ interface usePropsReturn {
|
|||||||
variables: VariablesContextType;
|
variables: VariablesContextType;
|
||||||
localVariables: VariableOption | VariableOption[];
|
localVariables: VariableOption | VariableOption[];
|
||||||
record: Record<string, any>;
|
record: Record<string, any>;
|
||||||
|
/**
|
||||||
|
* create 表示创建表单,update 表示更新表单
|
||||||
|
*/
|
||||||
|
formBlockType: 'create' | 'update';
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -33,7 +37,8 @@ export const FormLinkageRules = observer(
|
|||||||
(props: Props) => {
|
(props: Props) => {
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const { useProps, dynamicComponent } = props;
|
const { useProps, dynamicComponent } = props;
|
||||||
const { options, defaultValues, collectionName, form, variables, localVariables, record } = useProps();
|
const { options, defaultValues, collectionName, form, formBlockType, variables, localVariables, record } =
|
||||||
|
useProps();
|
||||||
const { getAllCollectionsInheritChain } = useCollectionManager();
|
const { getAllCollectionsInheritChain } = useCollectionManager();
|
||||||
|
|
||||||
const components = useMemo(() => ({ ArrayCollapse }), []);
|
const components = useMemo(() => ({ ArrayCollapse }), []);
|
||||||
@ -160,7 +165,7 @@ export const FormLinkageRules = observer(
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormBlockContext.Provider value={{ form }}>
|
<FormBlockContext.Provider value={{ form, type: formBlockType }}>
|
||||||
<RecordProvider record={record}>
|
<RecordProvider record={record}>
|
||||||
<FilterContext.Provider value={value}>
|
<FilterContext.Provider value={value}>
|
||||||
<SchemaComponent components={components} schema={schema} />
|
<SchemaComponent components={components} schema={schema} />
|
||||||
|
@ -64,7 +64,7 @@ import {
|
|||||||
useRecord,
|
useRecord,
|
||||||
useSortFields,
|
useSortFields,
|
||||||
} from '..';
|
} from '..';
|
||||||
import { BlockRequestContext, useFormBlockContext, useTableBlockContext } from '../block-provider';
|
import { BlockRequestContext, useFormBlockContext, useFormBlockType, useTableBlockContext } from '../block-provider';
|
||||||
import {
|
import {
|
||||||
FormActiveFieldsProvider,
|
FormActiveFieldsProvider,
|
||||||
findFilterTargets,
|
findFilterTargets,
|
||||||
@ -1154,6 +1154,7 @@ SchemaSettings.LinkageRules = function LinkageRules(props) {
|
|||||||
const variables = useVariables();
|
const variables = useVariables();
|
||||||
const localVariables = useLocalVariables();
|
const localVariables = useLocalVariables();
|
||||||
const record = useRecord();
|
const record = useRecord();
|
||||||
|
const { type: formBlockType } = useFormBlockType();
|
||||||
const type = props?.type || ['Action', 'Action.Link'].includes(fieldSchema['x-component']) ? 'button' : 'field';
|
const type = props?.type || ['Action', 'Action.Link'].includes(fieldSchema['x-component']) ? 'button' : 'field';
|
||||||
const gridSchema = findGridSchema(fieldSchema) || fieldSchema;
|
const gridSchema = findGridSchema(fieldSchema) || fieldSchema;
|
||||||
const schema = useMemo<ISchema>(
|
const schema = useMemo<ISchema>(
|
||||||
@ -1176,6 +1177,7 @@ SchemaSettings.LinkageRules = function LinkageRules(props) {
|
|||||||
variables,
|
variables,
|
||||||
localVariables,
|
localVariables,
|
||||||
record,
|
record,
|
||||||
|
formBlockType,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Form } from '@formily/core';
|
import { Form } from '@formily/core';
|
||||||
import { ISchema, Schema } from '@formily/react';
|
import { ISchema, Schema } from '@formily/react';
|
||||||
import _ from 'lodash';
|
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
import { useFormBlockType } from '../../../block-provider/FormBlockProvider';
|
||||||
import { CollectionFieldOptions } from '../../../collection-manager';
|
import { CollectionFieldOptions } from '../../../collection-manager';
|
||||||
import { useFlag } from '../../../flag-provider';
|
import { useFlag } from '../../../flag-provider';
|
||||||
import { useBlockCollection } from './useBlockCollection';
|
import { useBlockCollection } from './useBlockCollection';
|
||||||
@ -20,7 +20,7 @@ interface Props {
|
|||||||
/**
|
/**
|
||||||
* `useRecord` 返回的值
|
* `useRecord` 返回的值
|
||||||
*/
|
*/
|
||||||
record: Record<string, any>;
|
record?: Record<string, any>;
|
||||||
/**
|
/**
|
||||||
* `Filter` 组件中选中的字段的 `uiSchema`,比如设置 `数据范围` 的时候在左侧选择的字段
|
* `Filter` 组件中选中的字段的 `uiSchema`,比如设置 `数据范围` 的时候在左侧选择的字段
|
||||||
*/
|
*/
|
||||||
@ -40,7 +40,6 @@ interface Props {
|
|||||||
export const useVariableOptions = ({
|
export const useVariableOptions = ({
|
||||||
collectionField,
|
collectionField,
|
||||||
form,
|
form,
|
||||||
record,
|
|
||||||
uiSchema,
|
uiSchema,
|
||||||
operator,
|
operator,
|
||||||
noDisabled,
|
noDisabled,
|
||||||
@ -48,6 +47,7 @@ export const useVariableOptions = ({
|
|||||||
}: Props) => {
|
}: Props) => {
|
||||||
const { name: blockCollectionName } = useBlockCollection();
|
const { name: blockCollectionName } = useBlockCollection();
|
||||||
const { isInSetDefaultValueDialog } = useFlag() || {};
|
const { isInSetDefaultValueDialog } = useFlag() || {};
|
||||||
|
const { type: formBlockType } = useFormBlockType();
|
||||||
|
|
||||||
const fieldCollectionName = collectionField?.collectionName;
|
const fieldCollectionName = collectionField?.collectionName;
|
||||||
const userVariable = useUserVariable({
|
const userVariable = useUserVariable({
|
||||||
@ -80,10 +80,6 @@ export const useVariableOptions = ({
|
|||||||
targetFieldSchema,
|
targetFieldSchema,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 保证下面的 `_.isEmpty(record)` 结果符合预期,如果存在 `__parent` 字段,需要删除
|
|
||||||
record = { ...record };
|
|
||||||
delete record.__parent;
|
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
return [
|
return [
|
||||||
userVariable,
|
userVariable,
|
||||||
@ -95,7 +91,7 @@ export const useVariableOptions = ({
|
|||||||
fieldCollectionName !== blockCollectionName &&
|
fieldCollectionName !== blockCollectionName &&
|
||||||
isInSetDefaultValueDialog &&
|
isInSetDefaultValueDialog &&
|
||||||
iterationVariable,
|
iterationVariable,
|
||||||
!_.isEmpty(record) && currentRecordVariable,
|
formBlockType === 'update' && currentRecordVariable,
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
}, [
|
}, [
|
||||||
userVariable,
|
userVariable,
|
||||||
@ -106,7 +102,6 @@ export const useVariableOptions = ({
|
|||||||
blockCollectionName,
|
blockCollectionName,
|
||||||
isInSetDefaultValueDialog,
|
isInSetDefaultValueDialog,
|
||||||
iterationVariable,
|
iterationVariable,
|
||||||
record,
|
|
||||||
currentRecordVariable,
|
currentRecordVariable,
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user