refactor(DataBlock): filter form (#3785)

* refactor: migrate to modules

* refactor: add useFilterFormBlockProps

* refactor: add useFilterFormBlockDecoratorProps hook

* chore: avoid error

* refactor: use x-use-component-props instead of useProps

* chore: fix unit test

* chore: fix build
This commit is contained in:
Zeke Zhang 2024-03-27 20:52:29 +08:00 committed by GitHub
parent 06980fd87d
commit d6f38495a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 182 additions and 74 deletions

View File

@ -24,6 +24,8 @@ import { useTableBlockDecoratorProps } from '../modules/blocks/data-blocks/table
import { useListBlockDecoratorProps } from '../modules/blocks/data-blocks/list/hooks/useListBlockDecoratorProps'; import { useListBlockDecoratorProps } from '../modules/blocks/data-blocks/list/hooks/useListBlockDecoratorProps';
import { useTableSelectorDecoratorProps } from '../modules/blocks/data-blocks/table-selector/hooks/useTableSelectorDecoratorProps'; import { useTableSelectorDecoratorProps } from '../modules/blocks/data-blocks/table-selector/hooks/useTableSelectorDecoratorProps';
import { useCollapseBlockDecoratorProps } from '../modules/blocks/filter-blocks/collapse/hooks/useCollapseBlockDecoratorProps'; import { useCollapseBlockDecoratorProps } from '../modules/blocks/filter-blocks/collapse/hooks/useCollapseBlockDecoratorProps';
import { useFilterFormBlockProps } from '../modules/blocks/filter-blocks/form/hooks/useFilterFormBlockProps';
import { useFilterFormBlockDecoratorProps } from '../modules/blocks/filter-blocks/form/hooks/useFilterFormBlockDecoratorProps';
// TODO: delete this, replaced by `BlockSchemaComponentPlugin` // TODO: delete this, replaced by `BlockSchemaComponentPlugin`
export const BlockSchemaComponentProvider: React.FC = (props) => { export const BlockSchemaComponentProvider: React.FC = (props) => {
@ -58,6 +60,8 @@ export const BlockSchemaComponentProvider: React.FC = (props) => {
useListBlockDecoratorProps, useListBlockDecoratorProps,
useTableSelectorDecoratorProps, useTableSelectorDecoratorProps,
useCollapseBlockDecoratorProps, useCollapseBlockDecoratorProps,
useFilterFormBlockProps,
useFilterFormBlockDecoratorProps,
}} }}
> >
{props.children} {props.children}
@ -109,6 +113,8 @@ export class BlockSchemaComponentPlugin extends Plugin {
useListBlockDecoratorProps, useListBlockDecoratorProps,
useTableSelectorDecoratorProps, useTableSelectorDecoratorProps,
useCollapseBlockDecoratorProps, useCollapseBlockDecoratorProps,
useFilterFormBlockProps,
useFilterFormBlockDecoratorProps,
}); });
} }
} }

View File

@ -2,8 +2,9 @@ import React from 'react';
import { DatePickerProvider } from '../schema-component'; import { DatePickerProvider } from '../schema-component';
import { DefaultValueProvider } from '../schema-settings'; import { DefaultValueProvider } from '../schema-settings';
import { FormBlockProvider } from './FormBlockProvider'; import { FormBlockProvider } from './FormBlockProvider';
import { withDynamicSchemaProps } from '../application/hoc/withDynamicSchemaProps';
export const FilterFormBlockProvider = (props) => { export const FilterFormBlockProvider = withDynamicSchemaProps((props) => {
return ( return (
<DatePickerProvider value={{ utc: false }}> <DatePickerProvider value={{ utc: false }}>
<DefaultValueProvider isAllowToSetDefaultValue={() => false}> <DefaultValueProvider isAllowToSetDefaultValue={() => false}>
@ -11,4 +12,4 @@ export const FilterFormBlockProvider = (props) => {
</DefaultValueProvider> </DefaultValueProvider>
</DatePickerProvider> </DatePickerProvider>
); );
}; });

View File

@ -1,7 +1,7 @@
import { FormOutlined } from '@ant-design/icons'; import { FormOutlined } from '@ant-design/icons';
import React from 'react'; import React from 'react';
import { useSchemaInitializer, useSchemaInitializerItem } from '../../../../application'; import { useSchemaInitializer, useSchemaInitializerItem } from '../../../../application';
import { createFilterFormBlockSchema } from '../../../../schema-initializer/utils'; import { createFilterFormBlockSchema } from './createFilterFormBlockSchema';
import { FilterBlockInitializer } from '../../../../schema-initializer/items/FilterBlockInitializer'; import { FilterBlockInitializer } from '../../../../schema-initializer/items/FilterBlockInitializer';
import { Collection, CollectionFieldOptions } from '../../../../data-source'; import { Collection, CollectionFieldOptions } from '../../../../data-source';
@ -25,10 +25,9 @@ export const FilterFormBlockInitializer = ({
componentType={'FilterFormItem'} componentType={'FilterFormItem'}
templateWrap={(templateSchema, { item }) => { templateWrap={(templateSchema, { item }) => {
const s = createFilterFormBlockSchema({ const s = createFilterFormBlockSchema({
template: templateSchema, templateSchema: templateSchema,
dataSource: item.dataSource, dataSource: item.dataSource,
collection: item.name || item.collectionName, collectionName: item.name || item.collectionName,
settings: 'blockSettings:filterForm',
}); });
if (item.template && item.mode === 'reference') { if (item.template && item.mode === 'reference') {
s['x-template-key'] = item.template.key; s['x-template-key'] = item.template.key;
@ -38,9 +37,8 @@ export const FilterFormBlockInitializer = ({
onCreateBlockSchema={({ item }) => { onCreateBlockSchema={({ item }) => {
return insert( return insert(
createFilterFormBlockSchema({ createFilterFormBlockSchema({
collection: item.collectionName || item.name, collectionName: item.collectionName || item.name,
dataSource: item.dataSource, dataSource: item.dataSource,
settings: 'blockSettings:filterForm',
}), }),
); );
}} }}

View File

@ -0,0 +1,106 @@
import { createFilterFormBlockSchema } from '../createFilterFormBlockSchema';
vi.mock('@formily/shared', () => {
return {
uid: () => 'mocked-uid',
};
});
describe('createFilterFormBlockSchema', () => {
test('should return the correct schema', () => {
const schema = createFilterFormBlockSchema({
collectionName: 'myCollection',
dataSource: 'myDataSource',
templateSchema: { type: 'string' },
});
expect(schema).toMatchInlineSnapshot(`
{
"properties": {
"mocked-uid": {
"properties": {
"grid": {
"type": "string",
},
"mocked-uid": {
"type": "void",
"x-component": "ActionBar",
"x-component-props": {
"layout": "one-column",
"style": {
"float": "right",
},
},
"x-initializer": "filterForm:configureActions",
},
},
"type": "void",
"x-component": "FormV2",
"x-use-component-props": "useFilterFormBlockProps",
},
},
"type": "void",
"x-component": "CardItem",
"x-decorator": "FilterFormBlockProvider",
"x-decorator-props": {
"collection": "myCollection",
"dataSource": "myDataSource",
},
"x-filter-operators": {},
"x-filter-targets": [],
"x-settings": "blockSettings:filterForm",
"x-toolbar": "BlockSchemaToolbar",
"x-use-decorator-props": "useFilterFormBlockDecoratorProps",
}
`);
});
test('should return the correct schema without templateSchema', () => {
const schema = createFilterFormBlockSchema({
collectionName: 'myCollection',
dataSource: 'myDataSource',
});
expect(schema).toMatchInlineSnapshot(`
{
"properties": {
"mocked-uid": {
"properties": {
"grid": {
"type": "void",
"x-component": "Grid",
"x-initializer": "filterForm:configureFields",
},
"mocked-uid": {
"type": "void",
"x-component": "ActionBar",
"x-component-props": {
"layout": "one-column",
"style": {
"float": "right",
},
},
"x-initializer": "filterForm:configureActions",
},
},
"type": "void",
"x-component": "FormV2",
"x-use-component-props": "useFilterFormBlockProps",
},
},
"type": "void",
"x-component": "CardItem",
"x-decorator": "FilterFormBlockProvider",
"x-decorator-props": {
"collection": "myCollection",
"dataSource": "myDataSource",
},
"x-filter-operators": {},
"x-filter-targets": [],
"x-settings": "blockSettings:filterForm",
"x-toolbar": "BlockSchemaToolbar",
"x-use-decorator-props": "useFilterFormBlockDecoratorProps",
}
`);
});
});

View File

@ -0,0 +1,57 @@
import { ISchema } from '@formily/react';
import { uid } from '@formily/shared';
export const createFilterFormBlockSchema = (options: {
collectionName: string;
dataSource: string;
templateSchema?: ISchema;
}) => {
const { collectionName, dataSource, templateSchema } = options;
if (!collectionName || !dataSource) {
throw new Error('collectionName and dataSource are required');
}
const schema: ISchema = {
type: 'void',
'x-decorator': 'FilterFormBlockProvider',
'x-use-decorator-props': 'useFilterFormBlockDecoratorProps',
'x-decorator-props': {
dataSource,
collection: collectionName,
},
'x-toolbar': 'BlockSchemaToolbar',
'x-settings': 'blockSettings:filterForm',
'x-component': 'CardItem',
// 保存当前筛选区块所能过滤的数据区块
'x-filter-targets': [],
// 用于存储用户设置的每个字段的运算符,目前仅筛选表单区块支持自定义
'x-filter-operators': {},
properties: {
[uid()]: {
type: 'void',
'x-component': 'FormV2',
'x-use-component-props': 'useFilterFormBlockProps',
properties: {
grid: templateSchema || {
type: 'void',
'x-component': 'Grid',
'x-initializer': 'filterForm:configureFields',
},
[uid()]: {
type: 'void',
'x-initializer': 'filterForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
style: {
float: 'right',
},
},
},
},
},
},
};
return schema;
};

View File

@ -0,0 +1 @@
export function useFilterFormBlockDecoratorProps() {}

View File

@ -0,0 +1,5 @@
import { useFormBlockProps } from '../../../../../block-provider/FormBlockProvider';
export function useFilterFormBlockProps() {
return useFormBlockProps();
}

View File

@ -123,7 +123,6 @@ export * from './buttons';
export * from './items'; export * from './items';
export { export {
createDetailsBlockSchema, createDetailsBlockSchema,
createFilterFormBlockSchema,
createFormBlockSchema, createFormBlockSchema,
createReadPrettyFormBlockSchema, createReadPrettyFormBlockSchema,
createTableBlockSchema, createTableBlockSchema,

View File

@ -1154,71 +1154,6 @@ export const createFormBlockSchema = (options: {
return schema; return schema;
}; };
export const createFilterFormBlockSchema = (options) => {
const {
formItemInitializers = 'filterForm:configureFields',
actionInitializers = 'filterForm:configureActions',
collection,
resource,
association,
dataSource,
action,
template,
settings,
...others
} = options;
const resourceName = resource || association || collection;
const schema: ISchema = {
type: 'void',
'x-decorator': 'FilterFormBlockProvider',
'x-decorator-props': {
...others,
action,
resource: resourceName,
dataSource,
collection,
association,
},
'x-toolbar': 'BlockSchemaToolbar',
...(settings ? { 'x-settings': settings } : { 'x-designer': 'FormV2.FilterDesigner' }),
'x-component': 'CardItem',
// 保存当前筛选区块所能过滤的数据区块
'x-filter-targets': [],
// 用于存储用户设置的每个字段的运算符,目前仅筛选表单区块支持自定义
'x-filter-operators': {},
properties: {
[uid()]: {
type: 'void',
'x-component': 'FormV2',
'x-component-props': {
useProps: '{{ useFormBlockProps }}',
},
properties: {
grid: template || {
type: 'void',
'x-component': 'Grid',
'x-initializer': formItemInitializers,
properties: {},
},
[uid()]: {
type: 'void',
'x-initializer': actionInitializers,
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
style: {
float: 'right',
},
},
properties: {},
},
},
},
},
};
return schema;
};
/** /**
* @deprecated * @deprecated
* 使 createDetailsBlockSchema * 使 createDetailsBlockSchema