fix(Collapse): resolve error when using variables in data scope (#5195)

* refactor: use common hook to reduce code size

* fix(Collapse): resolve error when using variables in data scope
This commit is contained in:
Zeke Zhang 2024-09-04 21:17:43 +08:00 committed by GitHub
parent 3c89e0342e
commit 1034aaa81d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 22 additions and 71 deletions

View File

@ -28,6 +28,7 @@ import {
useCollectionRecord,
useDataSourceHeaders,
useFormActiveFields,
useParsedFilter,
useRouterBasename,
useTableBlockContext,
} from '../..';
@ -1247,6 +1248,7 @@ export const useAssociationFilterBlockProps = () => {
const { props: blockProps } = useBlockRequestContext();
const headers = useDataSourceHeaders(blockProps?.dataSource);
const cm = useCollectionManager_deprecated();
const { filter, parseVariableLoading } = useParsedFilter({ filterOption: field.componentProps?.params?.filter });
let list, handleSearchInput, params, run, data, valueKey, labelKey, filterKey;
@ -1266,6 +1268,7 @@ export const useAssociationFilterBlockProps = () => {
pageSize: 200,
page: 1,
...field.componentProps?.params,
filter,
},
},
{
@ -1277,12 +1280,20 @@ export const useAssociationFilterBlockProps = () => {
useEffect(() => {
// 由于选项字段不需要触发当前请求,所以请求单独在关系字段的时候触发
if (!isOptionalField(collectionField)) {
if (!isOptionalField(collectionField) && parseVariableLoading === false) {
run();
}
// do not format the dependencies
}, [collectionField, labelKey, run, valueKey, field.componentProps?.params, field.componentProps?.params?.sort]);
}, [
collectionField,
labelKey,
run,
valueKey,
field.componentProps?.params,
field.componentProps?.params?.sort,
parseVariableLoading,
]);
if (!collectionField) {
return {};

View File

@ -9,21 +9,15 @@
import { GeneralField } from '@formily/core';
import { useField, useFieldSchema } from '@formily/react';
import { reaction } from '@formily/reactive';
import { flatten, getValuesByPath } from '@nocobase/utils/client';
import _, { isString } from 'lodash';
import { isString } from 'lodash';
import cloneDeep from 'lodash/cloneDeep';
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { createContext, useCallback, useContext, useMemo } from 'react';
import { useParsedFilter } from '../../../block-provider/hooks/useParsedFilter';
import { useCollectionManager_deprecated, useCollection_deprecated } from '../../../collection-manager';
import { Collection } from '../../../data-source';
import { isInFilterFormBlock } from '../../../filter-provider';
import { mergeFilter } from '../../../filter-provider/utils';
import { useRecord } from '../../../record-provider';
import { useParseDataScopeFilter } from '../../../schema-settings';
import { DEBOUNCE_WAIT } from '../../../variables';
import { getPath } from '../../../variables/utils/getPath';
import { getVariableName } from '../../../variables/utils/getVariableName';
import { isVariable } from '../../../variables/utils/isVariable';
import { useDesignable } from '../../hooks';
import { AssociationFieldMode } from './AssociationFieldModeProvider';
import { AssociationFieldContext } from './context';
@ -65,66 +59,12 @@ export default function useServiceOptions(props) {
const { getField } = useCollection_deprecated();
const { getCollectionJoinField } = useCollectionManager_deprecated();
const record = useRecord();
const { parseFilter, findVariable } = useParseDataScopeFilter();
const [fieldServiceFilter, setFieldServiceFilter] = useState(null);
useEffect(() => {
const filterFromSchema = isString(fieldSchema?.['x-component-props']?.service?.params?.filter)
const filterParams =
(isString(fieldSchema?.['x-component-props']?.service?.params?.filter)
? field.componentProps?.service?.params?.filter
: fieldSchema?.['x-component-props']?.service?.params?.filter;
: fieldSchema?.['x-component-props']?.service?.params?.filter) || service?.params?.filter;
const _run = async () => {
const result = await parseFilter(mergeFilter([filterFromSchema || service?.params?.filter]));
setFieldServiceFilter(result);
};
const run = _.debounce(_run, DEBOUNCE_WAIT);
_run();
const dispose = reaction(
() => {
// 这一步主要是为了使 reaction 能够收集到依赖
const flat = flatten(filterFromSchema, {
breakOn({ key }) {
return key.startsWith('$') && key !== '$and' && key !== '$or';
},
transformValue(value) {
if (!isVariable(value)) {
return value;
}
const variableName = getVariableName(value);
const variable = findVariable(variableName);
if (process.env.NODE_ENV !== 'production' && !variable) {
throw new Error(`useServiceOptions: can not find variable ${variableName}`);
}
const result = getValuesByPath(
{
[variableName]: variable?.ctx || {},
},
getPath(value),
);
return result;
},
});
return flat;
},
run,
{
equals: _.isEqual,
},
);
return dispose;
}, [
field.componentProps?.service?.params?.filter,
fieldSchema,
findVariable,
parseFilter,
record,
service?.params?.filter,
]);
const { filter: parsedFilterParams } = useParsedFilter({ filterOption: filterParams });
const collectionField = useMemo(() => {
return getField(fieldSchema.name) || getCollectionJoinField(fieldSchema?.['x-collection-field']);
@ -143,7 +83,7 @@ export default function useServiceOptions(props) {
},
}
: null,
fieldServiceFilter,
parsedFilterParams,
]),
isOToAny &&
sourceValue !== undefined &&
@ -171,7 +111,7 @@ export default function useServiceOptions(props) {
collectionField?.interface,
collectionField?.foreignKey,
fieldSchema,
fieldServiceFilter,
parsedFilterParams,
sourceValue,
useOriginalFilter,
]);