diff --git a/packages/core/client/src/schema-component/antd/association-field/AssociationSelect.tsx b/packages/core/client/src/schema-component/antd/association-field/AssociationSelect.tsx
index 250dc7432..54fdb617a 100644
--- a/packages/core/client/src/schema-component/antd/association-field/AssociationSelect.tsx
+++ b/packages/core/client/src/schema-component/antd/association-field/AssociationSelect.tsx
@@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next';
import { RecordProvider, useAPIClient, useApp, useCollectionRecordData } from '../../../';
import { isVariable } from '../../../variables/utils/isVariable';
import { getInnermostKeyAndValue } from '../../common/utils/uitls';
-import { RemoteSelectProps } from '../remote-select';
+import { RemoteSelectProps, RemoteSelect } from '../remote-select';
import useServiceOptions, { useAssociationFieldContext } from './hooks';
export type AssociationSelectProps
= RemoteSelectProps
& {
@@ -60,8 +60,6 @@ const InternalAssociationSelect = observer(
const resource = api.resource(collectionField.target);
const linkageFields = filterAnalyses(field.componentProps?.service?.params?.filter);
const recordData = useCollectionRecordData();
- const app = useApp();
- const RemoteSelect = useMemo(() => app.getComponent('RemoteSelect'), [app]);
useEffect(() => {
const initValue = isVariable(field.value) ? undefined : field.value;
@@ -169,7 +167,6 @@ export const AssociationSelectReadPretty = connect(
(props: any) => {
const service = useServiceOptions(props);
const app = useApp();
- const RemoteSelect = useMemo(() => app.getComponent('RemoteSelect'), [app]) as any;
if (props.fieldNames) {
return ;
}
diff --git a/packages/core/client/src/schema-component/antd/remote-select/RemoteSelect.tsx b/packages/core/client/src/schema-component/antd/remote-select/RemoteSelect.tsx
index 03c0684e0..25601c2be 100644
--- a/packages/core/client/src/schema-component/antd/remote-select/RemoteSelect.tsx
+++ b/packages/core/client/src/schema-component/antd/remote-select/RemoteSelect.tsx
@@ -136,7 +136,7 @@ const InternalRemoteSelect = connect(
...service,
headers,
params: {
- pageSize: 200,
+ pageSize: fieldNames['formula'] ? 9999 : 200,
...service?.params,
filter: service?.params?.filter,
},
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/select/Select.tsx b/packages/core/client/src/schema-component/antd/select/FormulaSelect.tsx
similarity index 68%
rename from packages/plugins/@hera/plugin-core/src/client/schema-components/select/Select.tsx
rename to packages/core/client/src/schema-component/antd/select/FormulaSelect.tsx
index 132205679..4b49e9d53 100644
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/select/Select.tsx
+++ b/packages/core/client/src/schema-component/antd/select/FormulaSelect.tsx
@@ -1,12 +1,11 @@
-import { CloseCircleFilled, CloseOutlined, LoadingOutlined } from '@ant-design/icons';
-import { connect, mapProps, mapReadPretty, useFieldSchema, useForm } from '@formily/react';
+import { CloseCircleFilled, CloseOutlined } from '@ant-design/icons';
+import { useFieldSchema, useForm } from '@formily/react';
import { isValid, toArr } from '@formily/shared';
import { isPlainObject } from '@nocobase/utils/client';
import type { SelectProps } from 'antd';
import { Select as AntdSelect, Empty, Spin, Tag } from 'antd';
import React, { useEffect, useMemo, useState } from 'react';
-import { ReadPretty } from './ReadPretty';
-import { FieldNames, defaultFieldNames, getCurrentOptions } from './utils';
+import { FieldNames, getCurrentOptions } from './utils';
import { useAPIClient, useCollection_deprecated, useRequest } from '@nocobase/client';
import { useAsyncEffect } from 'ahooks';
@@ -21,7 +20,7 @@ type Props = SelectProps & {
const isEmptyObject = (val: any) => !isValid(val) || (typeof val === 'object' && Object.keys(val).length === 0);
const ObjectSelect = (props: Props) => {
- const { value, options, onChange, fieldNames, mode, loading, rawOptions, defaultValue, ...others } = props;
+ const { value, options, onChange, mode, fieldNames, loading, rawOptions, defaultValue, ...others } = props;
const [defoptions, setDefOptions] = useState();
const fieldSchema = useFieldSchema();
const collectionName = fieldSchema['collectionName'];
@@ -45,6 +44,12 @@ const ObjectSelect = (props: Props) => {
setDefOptions(changOptions);
}
}, [filterField?.filter, collectionName]);
+ useEffect(() => {
+ if (collectionName && fieldSchema['name'].toString().includes('custom') && defaultValue) {
+ const name = fieldSchema['name'].toString().split('.')[1];
+ form.values['custom'][name] = defaultValue?.[fieldNames.value];
+ }
+ }, []);
const toValue = (v: any) => {
if (isEmptyObject(v)) {
return;
@@ -107,7 +112,7 @@ const ObjectSelect = (props: Props) => {
} else {
onChange?.(current.shift() || null);
}
- if (collectionName) {
+ if (collectionName && fieldSchema['name'].toString().includes('custom')) {
const name = fieldSchema['name'].toString().split('.')[1];
form.values['custom'][name] = changed?.['value'];
}
@@ -131,8 +136,6 @@ const ObjectSelect = (props: Props) => {
);
};
-const filterOption = (input, option) => (option?.label ?? '').toLowerCase().includes((input || '').toLowerCase());
-
const replacePlaceholders = (inputStr, values) => {
return inputStr.replace(/{{(.*?)}}/g, function (match, placeholder) {
return Object.prototype.hasOwnProperty.call(values, placeholder) ? values[placeholder] : match;
@@ -200,89 +203,25 @@ const useLabelOptions = (others) => {
}
return others;
};
-const InternalSelect = connect(
- (props: Props) => {
- const { objectValue, loading, value, rawOptions, defaultValue, ...others } = props;
- let mode: any = props.multiple ? 'multiple' : props.mode;
- if (mode && !['multiple', 'tags'].includes(mode)) {
- mode = undefined;
- }
- const modifiedProps = useLabelOptions(others);
- if (objectValue) {
- return (
-
- );
- }
- const toValue = (v) => {
- if (['tags', 'multiple'].includes(props.mode) || props.multiple) {
- if (v) {
- return toArr(v);
- }
- return undefined;
- }
- return v;
- };
- return (
- ,
- }}
- popupMatchSelectWidth={false}
- notFoundContent={loading ? : }
- value={toValue(value)}
- defaultValue={toValue(defaultValue)}
- tagRender={(props) => {
- return (
- // @ts-ignore
- }
- {...props}
- >
- {props.label}
-
- );
- }}
- {...others}
- onChange={(changed) => {
- props.onChange?.(changed === undefined ? null : changed);
- }}
- mode={mode}
- />
- );
- },
- mapProps(
- {
- dataSource: 'options',
- },
- (props, field) => {
- return {
- ...props,
- fieldNames: { ...defaultFieldNames, ...props.fieldNames },
- suffixIcon: field?.['loading'] || field?.['validating'] ? : props.suffixIcon,
- };
- },
- ),
- mapReadPretty(ReadPretty),
-);
-export const Select = InternalSelect as unknown as typeof InternalSelect & {
- ReadPretty: typeof ReadPretty;
+const FormulaSelect = (props) => {
+ const { objectValue, loading, value, rawOptions, defaultValue, ...others } = props;
+ let mode: any = props.multiple ? 'multiple' : props.mode;
+ if (mode && !['multiple', 'tags'].includes(mode)) {
+ mode = undefined;
+ }
+ const modifiedProps = useLabelOptions(others);
+
+ return (
+
+ );
};
-Select.ReadPretty = ReadPretty;
-
-export default Select;
+export default FormulaSelect;
diff --git a/packages/core/client/src/schema-component/antd/select/Select.tsx b/packages/core/client/src/schema-component/antd/select/Select.tsx
index 3d9784817..a1473336a 100644
--- a/packages/core/client/src/schema-component/antd/select/Select.tsx
+++ b/packages/core/client/src/schema-component/antd/select/Select.tsx
@@ -7,6 +7,7 @@ import { Select as AntdSelect, Empty, Spin, Tag } from 'antd';
import React from 'react';
import { ReadPretty } from './ReadPretty';
import { FieldNames, defaultFieldNames, getCurrentOptions } from './utils';
+import FormulaSelect from './FormulaSelect';
type Props = SelectProps & {
objectValue?: boolean;
@@ -103,6 +104,9 @@ const InternalSelect = connect(
if (mode && !['multiple', 'tags'].includes(mode)) {
mode = undefined;
}
+ if ('formula' in others.fieldNames || 'collection' in props) {
+ return ;
+ }
if (objectValue) {
return (
{
const flatValue = flat.unflatten(values);
const flatFieldSchema = flat.unflatten(filterSchemaItem);
flatValue['$and'] = flatValue['$and']?.filter(Boolean);
+ flatFieldSchema['$and'] = flatFieldSchema['$and']?.filter(Boolean);
return {
$and: [flatValue, flatFieldSchema],
};
diff --git a/packages/plugins/@hera/plugin-core/src/client/index.tsx b/packages/plugins/@hera/plugin-core/src/client/index.tsx
index e0c8b0c2f..031df1986 100644
--- a/packages/plugins/@hera/plugin-core/src/client/index.tsx
+++ b/packages/plugins/@hera/plugin-core/src/client/index.tsx
@@ -43,15 +43,7 @@ import {
GroupBlockConfigure,
SignatureInput,
} from './components';
-import {
- AutoComplete,
- DatePicker,
- GroupBlock,
- InternalPDFViewer,
- MenuDesigner,
- RemoteSelect,
- Select,
-} from './schema-components';
+import { AutoComplete, DatePicker, GroupBlock, InternalPDFViewer, MenuDesigner } from './schema-components';
import {
CreateSubmitActionInitializer,
FilterFormItem,
@@ -186,8 +178,6 @@ export class PluginCoreClient extends Plugin {
PDFViewerProvider,
PDFViwer: InternalPDFViewer,
PageLayout,
- RemoteSelect,
- Select,
SettingBlock: SettingBlockInitializer,
SheetBlock,
SheetBlockInitializer,
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/index.ts b/packages/plugins/@hera/plugin-core/src/client/schema-components/index.ts
index 5d363e12e..1547cd072 100644
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/index.ts
+++ b/packages/plugins/@hera/plugin-core/src/client/schema-components/index.ts
@@ -3,5 +3,3 @@ export * from './blocks/GroupBlock';
export * from './blocks/PDFViewer';
export * from './date-picker';
export * from './deprecated/ExtendedMenuDesigner';
-export * from './remote-select';
-export * from './select/Select';
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/remote-select/ReadPretty.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-components/remote-select/ReadPretty.tsx
deleted file mode 100644
index 46dafa37e..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/remote-select/ReadPretty.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { observer, useField, useFieldSchema } from '@formily/react';
-import React from 'react';
-import { getValues } from './shared';
-import { defaultFieldNames, useActionContext, useRecord, useRequest } from '@nocobase/client';
-import { Select } from '../select';
-
-export const ReadPretty = observer(
- (props: any) => {
- const fieldNames = { ...defaultFieldNames, ...props.fieldNames };
- const field = useField();
- const fieldSchema = useFieldSchema();
- const record = useRecord();
- const { snapshot } = useActionContext();
-
- const { data } = useRequest<{
- data: any[];
- }>(
- snapshot
- ? async () => ({
- data: record[fieldSchema.name],
- })
- : {
- action: 'list',
- ...props.service,
- params: {
- paginate: false,
- filter: {
- [fieldNames.value]: {
- $in: getValues(field.value, fieldNames),
- },
- },
- },
- },
- {
- refreshDeps: [props.service, field.value],
- },
- );
-
- return ;
- },
- { displayName: 'ReadPretty' },
-);
diff --git a/packages/plugins/@hera/plugin-core/src/client/schema-components/remote-select/RemoteSelect.tsx b/packages/plugins/@hera/plugin-core/src/client/schema-components/remote-select/RemoteSelect.tsx
deleted file mode 100644
index 4ce9dc36b..000000000
--- a/packages/plugins/@hera/plugin-core/src/client/schema-components/remote-select/RemoteSelect.tsx
+++ /dev/null
@@ -1,279 +0,0 @@
-import { LoadingOutlined } from '@ant-design/icons';
-import { connect, mapProps, mapReadPretty, useFieldSchema } from '@formily/react';
-import { Divider, SelectProps, Tag } from 'antd';
-import dayjs from 'dayjs';
-import { uniqBy } from 'lodash';
-import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
-import { ReadPretty } from './ReadPretty';
-import {
- defaultFieldNames,
- mergeFilter,
- useCollection_deprecated,
- useCollectionManager_deprecated,
- useCompile,
- useRequest,
-} from '@nocobase/client';
-import { Select } from '../select';
-const EMPTY = 'N/A';
-
-export type ResourceActionOptions = {
- resource?: string;
- resourceOf?: any;
- action?: string;
- params?: P;
-};
-
-export type RemoteSelectProps
= SelectProps
& {
- objectValue?: boolean;
- onChange?: (v: any) => void;
- target: string;
- wait?: number;
- manual?: boolean;
- mapOptions?: (data: any) => RemoteSelectProps['fieldNames'];
- targetField?: any;
- service: ResourceActionOptions
;
- CustomDropdownRender?: (v: any) => any;
-};
-
-const InternalRemoteSelect = connect(
- (props: RemoteSelectProps) => {
- const {
- fieldNames = {},
- service = {},
- wait = 300,
- value,
- defaultValue,
- objectValue,
- manual = true,
- mapOptions,
- targetField: _targetField,
- CustomDropdownRender,
- ...others
- } = props;
- const [open, setOpen] = useState(false);
- const firstRun = useRef(false);
- const fieldSchema = useFieldSchema();
- const isQuickAdd = fieldSchema['x-component-props']?.addMode === 'quickAdd';
- const { getField } = useCollection_deprecated();
- const searchData = useRef(null);
- const { getCollectionJoinField, getInterface } = useCollectionManager_deprecated();
- const collectionField = getField(fieldSchema.name) || getCollectionJoinField(fieldSchema.name as string);
- const targetField =
- _targetField ||
- (collectionField?.target &&
- fieldNames?.label &&
- getCollectionJoinField(`${collectionField.target}.${fieldNames.label}`));
-
- const operator = useMemo(() => {
- if (targetField?.interface) {
- return getInterface(targetField.interface)?.filterable?.operators?.[0]?.value || '$includes';
- }
- return '$includes';
- }, [targetField]);
- const compile = useCompile();
-
- const mapOptionsToTags = useCallback(
- (options) => {
- try {
- return options
- .filter((v) => ['number', 'string'].includes(typeof v[fieldNames.value]))
- .map((option) => {
- let label = compile(option[fieldNames.label]);
-
- if (targetField?.uiSchema?.enum) {
- if (Array.isArray(label)) {
- label = label
- .map((item, index) => {
- const option = targetField.uiSchema.enum.find((i) => i.value === item);
- if (option) {
- return (
-
- {option?.label || item}
-
- );
- } else {
- return (
-
- {item}
-
- );
- }
- })
- .reverse();
- } else {
- const item = targetField.uiSchema.enum.find((i) => i.value === label);
- if (item) {
- label = (
-
- {item.label}
-
- );
- }
- }
- }
- if (targetField?.type === 'date') {
- label = dayjs(label).format('YYYY-MM-DD');
- }
-
- if (mapOptions) {
- return mapOptions({
- [fieldNames.label]: label || EMPTY,
- [fieldNames.value]: option[fieldNames.value],
- });
- }
- return {
- ...option,
- [fieldNames.label]: label || EMPTY,
- [fieldNames.value]: option[fieldNames.value],
- };
- })
- .filter(Boolean);
- } catch (err) {
- console.error(err);
- return options;
- }
- },
- [targetField?.uiSchema, fieldNames],
- );
- const { data, run, loading } = useRequest(
- {
- action: 'list',
- ...service,
- params: {
- pageSize: fieldNames['formula'] ? 9999 : 200,
- ...service?.params,
- filter: service?.params?.filter,
- },
- },
- {
- manual,
- debounceWait: wait,
- },
- );
- const runDep = useMemo(
- () =>
- JSON.stringify({
- service,
- fieldNames,
- }),
- [service, fieldNames],
- );
- const CustomRenderCom = useCallback(() => {
- if (searchData.current && CustomDropdownRender) {
- return (
- {
- searchData.current = null;
- setOpen(false);
- }}
- />
- );
- }
- return null;
- }, [searchData.current]);
-
- useEffect(() => {
- // Lazy load
- if (firstRun.current) {
- run();
- }
- }, [runDep]);
-
- const onSearch = async (search) => {
- run({
- filter: mergeFilter([
- search
- ? {
- [fieldNames.label]: {
- [operator]: search,
- },
- }
- : {},
- service?.params?.filter,
- ]),
- });
- searchData.current = search;
- };
-
- const options = useMemo(() => {
- const v = value || defaultValue;
- if (!data?.data?.length) {
- return v != null ? (Array.isArray(v) ? v : [v]) : [];
- }
- const valueOptions =
- (v != null && (Array.isArray(v) ? v : [{ ...v, [fieldNames.value]: v[fieldNames.value] || v }])) || [];
- return uniqBy(data?.data?.concat(valueOptions ?? []), fieldNames.value);
- }, [value, defaultValue, data?.data, fieldNames.value]);
- const onDropdownVisibleChange = (visible) => {
- setOpen(visible);
- searchData.current = null;
- if (visible) {
- run();
- }
- firstRun.current = true;
- };
-
- return (
-