feat: 添加自定义组件下拉框类型 (#436)

Reviewed-on: daoyoucloud/tachycode#436
Reviewed-by: sealday <zhanglin@daoyoucloud.com>
Co-authored-by: wjh <wwwjh0710@163.com>
Co-committed-by: wjh <wwwjh0710@163.com>
This commit is contained in:
wjh 2024-03-20 12:02:41 +08:00 committed by sealday
parent 0171f14358
commit db104c20ce
2 changed files with 122 additions and 15 deletions

View File

@ -43,7 +43,7 @@ export const SchemaSettingsRemove: FC<SchemaSettingsRemoveProps> = (props) => {
} }
await dn.remove(null, options); await dn.remove(null, options);
await confirm?.onOk?.(); await confirm?.onOk?.();
if (fieldSchema['x-component'] === 'Select' || fieldSchema['x-component'] === 'AutoComplete') { if (fieldSchema['collectionName']) {
delete form.values['custom'][fieldSchema['collectionName']]; delete form.values['custom'][fieldSchema['collectionName']];
} else { } else {
if (form.values['custom']?.[fieldName]) { if (form.values['custom']?.[fieldName]) {

View File

@ -24,10 +24,10 @@ import {
useFormBlockContext, useFormBlockContext,
useAPIClient, useAPIClient,
} from '@nocobase/client'; } from '@nocobase/client';
import { ConfigProvider } from 'antd'; import { ConfigProvider, Radio, Space } from 'antd';
import React, { memo, useCallback, useContext, useMemo } from 'react'; import React, { memo, useCallback, useContext, useMemo, Profiler } from 'react';
import { Schema, SchemaOptionsContext, observer, useField, useFieldSchema } from '@formily/react'; import { Schema, SchemaOptionsContext, observer, useField, useFieldSchema, useForm } from '@formily/react';
import { FormLayout } from '@formily/antd-v5'; import { ArrayItems, FormLayout } from '@formily/antd-v5';
import { uid } from '@formily/shared'; import { uid } from '@formily/shared';
import { Field, onFieldValueChange } from '@formily/core'; import { Field, onFieldValueChange } from '@formily/core';
import { import {
@ -41,12 +41,99 @@ import _ from 'lodash';
import { SchemaSettingsRemove } from '../../components/FormFilter/SchemaSettingsRemove'; import { SchemaSettingsRemove } from '../../components/FormFilter/SchemaSettingsRemove';
import { useTranslation } from '../../locale'; import { useTranslation } from '../../locale';
const FieldComponentProps: React.FC = observer(
(props) => {
const { scope, components } = useContext(SchemaOptionsContext);
const schema = {
type: 'object',
properties: {
mode: {
type: 'string',
enum: [
{
label: '{{ t("Single select") }}',
value: '',
},
],
'x-decorator': 'FormItem',
'x-component': 'Radio.Group',
'x-component-props': {
defaultValue: '',
},
},
options: {
title: '{{t("Options")}}',
type: 'array',
'x-decorator': 'FormItem',
'x-component': 'ArrayItems',
items: {
type: 'object',
properties: {
space: {
type: 'void',
'x-component': 'Space',
properties: {
sort: {
type: 'void',
'x-decorator': 'FormItem',
'x-component': 'ArrayItems.SortHandle',
},
label: {
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-component-props': {
placeholder: '{{t("Option label")}}',
},
required: true,
},
value: {
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-component-props': {
placeholder: '{{t("Option value")}}',
},
required: true,
},
remove: {
type: 'void',
'x-decorator': 'FormItem',
'x-component': 'ArrayItems.Remove',
},
},
},
},
},
properties: {
add: {
type: 'void',
title: '{{t("add")}}',
'x-component': 'ArrayItems.Addition',
},
},
},
},
};
console.log(scope, 'scope');
console.log(components, 'components');
return (
<SchemaComponentOptions scope={{ ...scope }} components={{ ArrayItems, FormItem, Space }}>
<SchemaComponent schema={schema} {...props} />
</SchemaComponentOptions>
);
},
{ displayName: 'FieldComponentProps' },
);
export const useFieldComponents = () => { export const useFieldComponents = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const options = [ const options = [
{ label: t('Input'), value: 'Input' }, { label: t('Input'), value: 'Input' },
{ label: t('AutoComplete'), value: 'AutoComplete' }, { label: t('AutoComplete'), value: 'AutoComplete' },
{ label: t('Select'), value: 'Select' }, { label: t('Select'), value: 'Select' },
// { label: t('CustomSelect***'), value: 'CustomSelect' },
]; ];
return { return {
options, options,
@ -77,7 +164,10 @@ export const FilterCustomItemInitializer: React.FC<{
const values = await FormDialog( const values = await FormDialog(
t('Add custom field'), t('Add custom field'),
() => ( () => (
<SchemaComponentOptions scope={{ ...scope, useCollectionManager_deprecated }} components={{ ...components }}> <SchemaComponentOptions
scope={{ ...scope, useCollectionManager_deprecated }}
components={{ ...components, FieldComponentProps }}
>
<FormLayout layout={'vertical'}> <FormLayout layout={'vertical'}>
<ConfigProvider locale={locale}> <ConfigProvider locale={locale}>
<SchemaComponent <SchemaComponent
@ -111,6 +201,13 @@ export const FilterCustomItemInitializer: React.FC<{
description: t('Select a collection field to use metadata of the field'), description: t('Select a collection field to use metadata of the field'),
'x-visible': false, 'x-visible': false,
}, },
props: {
type: 'object',
title: t('Component properties'),
'x-decorator': 'FormItem',
'x-component': 'FieldComponentProps',
'x-visible': false,
},
}, },
}} }}
/> />
@ -126,13 +223,23 @@ export const FilterCustomItemInitializer: React.FC<{
effects() { effects() {
onFieldValueChange('component', (field) => { onFieldValueChange('component', (field) => {
const name = field.value; const name = field.value;
const component = field.query('.collection').take() as Field; const collectionComponent = field.query('.collection').take() as Field;
const propsComponent = field.query('.props').take() as Field;
if (name === 'Select' || name === 'AutoComplete') { if (name === 'Select' || name === 'AutoComplete') {
component.setDisplay('visible'); collectionComponent.setDisplay('visible');
component.setRequired(true); collectionComponent.setRequired(true);
propsComponent.setDisplay('none');
propsComponent.setRequired(false);
} else if (name === 'CustomSelect') {
collectionComponent.setDisplay('none');
collectionComponent.setRequired(false);
propsComponent.setDisplay('visible');
propsComponent.setRequired(true);
} else { } else {
component.setDisplay('none'); collectionComponent.setDisplay('none');
component.setRequired(false); collectionComponent.setRequired(false);
propsComponent.setDisplay('none');
propsComponent.setRequired(false);
} }
}); });
}, },
@ -212,10 +319,10 @@ export const FilterItemCustomDesigner: React.FC = () => {
}} }}
/> />
) : null} ) : null}
{component !== 'Input' ? <SchemaSettingCollection /> : null} {component === 'Select' || component === 'AutoComplete' ? <SchemaSettingCollection /> : null}
{component !== 'Input' ? <SchemaSettingComponent /> : null} {component === 'Select' || component === 'AutoComplete' ? <SchemaSettingComponent /> : null}
{component !== 'Input' ? <EditTitleField /> : null} {component === 'Select' || component === 'AutoComplete' ? <EditTitleField /> : null}
{component !== 'Input' ? <EditFormulaTitleField /> : null} {component === 'Select' || component === 'AutoComplete' ? <EditFormulaTitleField /> : null}
<SchemaSettingsDivider /> <SchemaSettingsDivider />
<SchemaSettingsRemove <SchemaSettingsRemove
key="remove" key="remove"