fix: option should clear when data scope change (#2800)

* fix: option should clear when data scope change

* refactor: data scope linkage in association select
This commit is contained in:
katherinehhh 2023-10-12 10:06:49 +08:00 committed by GitHub
parent ebde1b236b
commit 843677c183
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 11 deletions

View File

@ -1,19 +1,45 @@
import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
import { RecursionField, connect, mapProps, observer, useField, useFieldSchema, useForm } from '@formily/react';
import { onFieldChange, onFormInputChange } from '@formily/core';
import { uid } from '@formily/shared';
import { Space, message } from 'antd';
import { isFunction } from 'mathjs';
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { RecordProvider, useAPIClient } from '../../../';
import { isVariable } from '../../../variables/utils/isVariable';
import { RemoteSelect, RemoteSelectProps } from '../remote-select';
import useServiceOptions, { useAssociationFieldContext } from './hooks';
import { getInnermostKeyAndValue } from '../../common/utils/uitls';
export type AssociationSelectProps<P = any> = RemoteSelectProps<P> & {
action?: string;
multiple?: boolean;
};
export const filterAnalyses = (filters): any[] => {
if (!filters) {
return;
}
const type = Object.keys(filters)[0] || '$and';
const conditions = filters[type];
const results = [];
conditions.map((c) => {
const jsonlogic = getInnermostKeyAndValue(c);
const operator = jsonlogic?.key;
if (!operator) {
return true;
}
const regex = /\{\{\$(?:[a-zA-Z_]\w*)\.([a-zA-Z_]\w*)(?:\.id)?\}\}/;
const fieldName = jsonlogic?.value.match(regex)?.[1];
if (fieldName) {
results.push(fieldName);
}
});
return results;
};
const InternalAssociationSelect = observer((props: AssociationSelectProps) => {
const { objectValue = true } = props;
const field: any = useField();
@ -22,10 +48,8 @@ const InternalAssociationSelect = observer((props: AssociationSelectProps) => {
const { options: collectionField } = useAssociationFieldContext();
const initValue = isVariable(props.value) ? undefined : props.value;
const value = Array.isArray(initValue) ? initValue.filter(Boolean) : initValue;
// 因为通过 Schema 的形式书写的组件,在值变更的时候 `value` 的值没有改变,所以需要维护一个 `innerValue` 来变更值
const [innerValue, setInnerValue] = useState(value);
const addMode = fieldSchema['x-component-props']?.addMode;
const isAllowAddNew = fieldSchema['x-add-new'];
const { t } = useTranslation();
@ -33,6 +57,26 @@ const InternalAssociationSelect = observer((props: AssociationSelectProps) => {
const form = useForm();
const api = useAPIClient();
const resource = api.resource(collectionField.target);
const linkageFields = filterAnalyses(field.componentProps?.service?.params?.filter);
useEffect(() => {
const id = uid();
form.addEffects(id, () => {
linkageFields?.forEach((v) => {
if (v) {
onFieldChange(v, () => {
if (field.value) {
props.onChange(null);
setInnerValue(null);
}
});
}
});
});
return () => {
form.removeEffects(id);
};
}, []);
const handleCreateAction = async (props) => {
const { search: value, callBack } = props;

View File

@ -151,13 +151,13 @@ export default function useServiceOptions(props) {
},
}
: null,
params?.filter && value?.length
? {
[fieldNames?.value]: {
['$in']: value,
},
}
: null,
// params?.filter && value?.length
// ? {
// [fieldNames?.value]: {
// ['$in']: value,
// },
// }
// : null,
],
'$or',
);

View File

@ -184,7 +184,7 @@ const InternalRemoteSelect = connect(
}
const valueOptions =
(v != null && (Array.isArray(v) ? v : [{ ...v, [fieldNames.value]: v[fieldNames.value] || v }])) || [];
return uniqBy(data?.data?.concat(valueOptions) || [], fieldNames.value);
return uniqBy(data?.data?.concat(valueOptions ?? []), fieldNames.value);
}, [value, defaultValue, data?.data, fieldNames.value]);
const onDropdownVisibleChange = (visible) => {
setOpen(visible);