fix: filter form drop-down selection to add data range (#3321)

* fix: filter form drop-down selection to add data range

* refactor: use existing code directly

* test: add tests

---------

Co-authored-by: zhangboya3 <zhangboya3@xiaomi.com>
Co-authored-by: Zeke Zhang <958414905@qq.com>
This commit is contained in:
by 2024-01-09 12:21:16 +08:00 committed by GitHub
parent c1149d75f1
commit effff269dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 511 additions and 7 deletions

View File

@ -1,8 +1,17 @@
import { SchemaSettings } from '../../../application/schema-settings';
import { useFieldSchema } from '@formily/react';
import { useField, useFieldSchema } from '@formily/react';
import _ from 'lodash';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { SchemaSettings } from '../../../application/schema-settings';
import { useFormBlockContext } from '../../../block-provider';
import { useCollection, useCollectionManager } from '../../../collection-manager';
import { useRecord } from '../../../record-provider';
import { SchemaSettingsDataScope, VariableInput, getShouldChange } from '../../../schema-settings';
import { useLocalVariables, useVariables } from '../../../variables';
import { useDesignable } from '../../hooks';
import { removeNullCondition } from '../filter';
import { DynamicComponentProps } from '../filter/DynamicComponent';
import { useIsFormReadPretty, useIsSelectFieldMode } from './FormItem.Settings';
import {
EditComponent,
EditDescription,
@ -32,6 +41,60 @@ export const filterFormItemSettings = new SchemaSettings({
name: 'validationRules',
Component: EditValidationRules,
},
{
name: 'setDataScope',
Component: SchemaSettingsDataScope,
useVisible() {
const isSelectFieldMode = useIsSelectFieldMode();
const isFormReadPretty = useIsFormReadPretty();
return isSelectFieldMode && !isFormReadPretty;
},
useComponentProps() {
const { getCollectionJoinField, getAllCollectionsInheritChain } = useCollectionManager();
const { getField } = useCollection();
const { form } = useFormBlockContext();
const record = useRecord();
const field = useField();
const fieldSchema = useFieldSchema();
const collectionField =
getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']);
const variables = useVariables();
const localVariables = useLocalVariables();
const { dn } = useDesignable();
return {
collectionName: collectionField?.target,
defaultFilter: fieldSchema?.['x-component-props']?.service?.params?.filter || {},
form,
dynamicComponent: (props: DynamicComponentProps) => {
return (
<VariableInput
{...props}
form={form}
collectionField={props.collectionField}
record={record}
shouldChange={getShouldChange({
collectionField: props.collectionField,
variables,
localVariables,
getAllCollectionsInheritChain,
})}
/>
);
},
onSubmit: ({ filter }) => {
filter = removeNullCondition(filter);
_.set(field.componentProps, 'service.params.filter', filter);
fieldSchema['x-component-props'] = field.componentProps;
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
'x-component-props': field.componentProps,
},
});
},
};
},
},
{
name: 'fieldMode',
Component: EditComponent,

View File

@ -1,7 +1,6 @@
import { ArrayCollapse, FormLayout } from '@formily/antd-v5';
import { Field } from '@formily/core';
import { ISchema, useField, useFieldSchema } from '@formily/react';
import { Select } from 'antd';
import _ from 'lodash';
import React from 'react';
import { useTranslation } from 'react-i18next';
@ -11,8 +10,8 @@ import { Collection, useCollection, useCollectionManager } from '../../../collec
import { useRecord } from '../../../record-provider';
import { generalSettingsItems } from '../../../schema-items/GeneralSettings';
import {
SchemaSettingsDateFormat,
SchemaSettingsDataScope,
SchemaSettingsDateFormat,
SchemaSettingsDefaultValue,
SchemaSettingsSortingRule,
isPatternDisabled,
@ -862,7 +861,7 @@ function isFileCollection(collection: Collection) {
return collection?.template === 'file';
}
function useIsFormReadPretty() {
export function useIsFormReadPretty() {
const { form } = useFormBlockContext();
return !!form?.readPretty;
}
@ -901,7 +900,7 @@ function useFieldMode() {
return fieldMode;
}
function useIsSelectFieldMode() {
export function useIsSelectFieldMode() {
const fieldMode = useFieldMode();
const isAssociationField = useIsAssociationField();
const isSelectFieldMode = isAssociationField && fieldMode === 'Select';

View File

@ -16,7 +16,6 @@ import {
import { useCompile, useDesignable, useFieldModeOptions } from '../../hooks';
import { useOperatorList } from '../filter/useOperators';
import { isFileCollection } from './FormItem';
export const findFilterOperators = (schema: Schema) => {
while (schema) {
if (schema['x-filter-operators']) {

View File

@ -11070,6 +11070,329 @@ export const oneTableBlockWithAddNewAndViewAndEditAndAssociationFields: PageConf
},
};
/**
* filter form
*/
export const oneFilterFormBlockWithAllAssociationFields: PageConfig = {
collections: generalWithAssociation,
pageSchema: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Page',
properties: {
wwjstoiggum: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'BlockInitializers',
properties: {
oogm3hoka7c: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Row',
properties: {
'5zbwfzh1742': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Col',
properties: {
pwm2ca6igf0: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-decorator': 'FilterFormBlockProvider',
'x-decorator-props': {
resource: 'general',
collection: 'general',
},
'x-designer': 'FormV2.FilterDesigner',
'x-component': 'CardItem',
'x-filter-targets': [],
'x-filter-operators': {},
properties: {
j2u0whpedfr: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'FormV2',
'x-component-props': {
useProps: '{{ useFormBlockProps }}',
},
properties: {
grid: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'FilterFormItemInitializers',
properties: {
y5gw4zxp20e: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Row',
properties: {
yflpc1gga26: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Col',
properties: {
oneToOneBelongsTo: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'string',
required: false,
'x-designer': 'FormItem.FilterFormDesigner',
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-collection-field': 'general.oneToOneBelongsTo',
'x-component-props': {
multiple: false,
fieldNames: {
label: 'id',
value: 'id',
},
},
'x-uid': '36aeb1yw2yy',
'x-async': false,
'x-index': 1,
},
},
'x-uid': '4hc93v9beuk',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'u7avxnfj90q',
'x-async': false,
'x-index': 1,
},
t2podb2p9ts: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Row',
properties: {
udslfw0t5vy: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Col',
properties: {
oneToOneHasOne: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'string',
required: false,
'x-designer': 'FormItem.FilterFormDesigner',
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-collection-field': 'general.oneToOneHasOne',
'x-component-props': {
multiple: false,
fieldNames: {
label: 'id',
value: 'id',
},
},
'x-uid': '945t8dkn7ab',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'alfh40hld9g',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'p0lrhxcpc30',
'x-async': false,
'x-index': 2,
},
zzfk0g3yfjw: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Row',
properties: {
f2dxs9mqnhu: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Col',
properties: {
oneToMany: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'string',
required: false,
'x-designer': 'FormItem.FilterFormDesigner',
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-collection-field': 'general.oneToMany',
'x-component-props': {
multiple: true,
fieldNames: {
label: 'id',
value: 'id',
},
},
'x-uid': '8j8w5rtdhux',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'zvua8m975ql',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'bo6emdzi0ug',
'x-async': false,
'x-index': 3,
},
'0klgdlg66ay': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Row',
properties: {
'12wu3wvgdhp': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Col',
properties: {
manyToOne: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'string',
required: false,
'x-designer': 'FormItem.FilterFormDesigner',
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-collection-field': 'general.manyToOne',
'x-component-props': {
multiple: false,
fieldNames: {
label: 'id',
value: 'id',
},
},
'x-uid': 'wcsgutero19',
'x-async': false,
'x-index': 1,
},
},
'x-uid': '0zebcqxbskn',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'bc7dwbg9thk',
'x-async': false,
'x-index': 4,
},
b7cs1das1cq: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Row',
properties: {
fza3rz9m06z: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Col',
properties: {
manyToMany: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'string',
required: false,
'x-designer': 'FormItem.FilterFormDesigner',
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-collection-field': 'general.manyToMany',
'x-component-props': {
multiple: true,
fieldNames: {
label: 'id',
value: 'id',
},
},
'x-uid': 'a04jfxgru7s',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'z0hmplugqhq',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'kmdbr7xi8xt',
'x-async': false,
'x-index': 5,
},
},
'x-uid': 'qiaicku011z',
'x-async': false,
'x-index': 1,
},
actions: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'FilterFormActionInitializers',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
style: {
float: 'right',
},
},
'x-uid': '1d1t3jlg0sq',
'x-async': false,
'x-index': 2,
},
},
'x-uid': 'sesnb8danbq',
'x-async': false,
'x-index': 1,
},
},
'x-uid': '652vjaqp29u',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'crpdy0e3icr',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'rzvgkigetmc',
'x-async': false,
'x-index': 1,
},
},
'x-uid': '9gdo96vyjl8',
'x-async': false,
'x-index': 1,
},
},
'x-uid': '19vrqfukj5j',
'x-async': true,
'x-index': 1,
},
};
/**
* 1. Table
* 2. Add new Form

View File

@ -2,6 +2,7 @@ import {
Page,
expect,
expectSettingsMenu,
oneFilterFormBlockWithAllAssociationFields,
oneTableBlockWithAddNewAndViewAndEditAndAssociationFields,
test,
} from '@nocobase/test/e2e';
@ -519,6 +520,29 @@ test.describe('form item & view form', () => {
});
});
test.describe('form item & filter form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneFilterFormBlockWithAllAssociationFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('block-item-CollectionField-general-filter-form-general.oneToOneBelongsTo-').hover();
await page.getByRole('button', { name: 'designer-schema-settings-CollectionField' }).hover();
},
supportedOptions: [
'Edit field title',
'Edit description',
'Set the data scope',
'Field component',
'Title field',
'Delete',
],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();

View File

@ -2,6 +2,7 @@ import {
Page,
expect,
expectSettingsMenu,
oneFilterFormBlockWithAllAssociationFields,
oneTableBlockWithAddNewAndViewAndEditAndAssociationFields,
test,
} from '@nocobase/test/e2e';
@ -518,6 +519,29 @@ test.describe('form item & view form', () => {
});
});
test.describe('form item & filter form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneFilterFormBlockWithAllAssociationFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('block-item-CollectionField-general-filter-form-general.oneToOneHasOne-').hover();
await page.getByRole('button', { name: 'designer-schema-settings-CollectionField' }).hover();
},
supportedOptions: [
'Edit field title',
'Edit description',
'Set the data scope',
'Field component',
'Title field',
'Delete',
],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();

View File

@ -2,6 +2,7 @@ import {
Page,
expect,
expectSettingsMenu,
oneFilterFormBlockWithAllAssociationFields,
oneTableBlockWithAddNewAndViewAndEditAndAssociationFields,
test,
} from '@nocobase/test/e2e';
@ -744,6 +745,29 @@ test.describe('form item & view form', () => {
});
});
test.describe('form item & filter form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneFilterFormBlockWithAllAssociationFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('block-item-CollectionField-general-filter-form-general.manyToMany-manyToMany').hover();
await page.getByRole('button', { name: 'designer-schema-settings-CollectionField' }).hover();
},
supportedOptions: [
'Edit field title',
'Edit description',
'Set the data scope',
'Field component',
'Title field',
'Delete',
],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();

View File

@ -2,6 +2,7 @@ import {
Page,
expect,
expectSettingsMenu,
oneFilterFormBlockWithAllAssociationFields,
oneTableBlockWithAddNewAndViewAndEditAndAssociationFields,
test,
} from '@nocobase/test/e2e';
@ -551,6 +552,29 @@ test.describe('form item & view form', () => {
});
});
test.describe('form item & filter form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneFilterFormBlockWithAllAssociationFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('block-item-CollectionField-general-filter-form-general.manyToOne-manyToOne').hover();
await page.getByRole('button', { name: 'designer-schema-settings-CollectionField' }).hover();
},
supportedOptions: [
'Edit field title',
'Edit description',
'Set the data scope',
'Field component',
'Title field',
'Delete',
],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();

View File

@ -2,6 +2,7 @@ import {
Page,
expect,
expectSettingsMenu,
oneFilterFormBlockWithAllAssociationFields,
oneTableBlockWithAddNewAndViewAndEditAndAssociationFields,
test,
} from '@nocobase/test/e2e';
@ -563,6 +564,29 @@ test.describe('form item & view form', () => {
});
});
test.describe('form item & filter form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneFilterFormBlockWithAllAssociationFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('block-item-CollectionField-general-filter-form-general.oneToMany-oneToMany').hover();
await page.getByRole('button', { name: 'designer-schema-settings-CollectionField' }).hover();
},
supportedOptions: [
'Edit field title',
'Edit description',
'Set the data scope',
'Field component',
'Title field',
'Delete',
],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();