From ef8e4aed485ac38296821751072d759cbe701e2f Mon Sep 17 00:00:00 2001 From: Zeke Zhang <958414905@qq.com> Date: Mon, 20 May 2024 16:50:34 +0800 Subject: [PATCH] fix(filter-form): fix operator not valid in block templates (#4390) * fix(filter-form): fix operator not valid in block templates * test: add e2e test * test: clear data templates * chore: fix e2e tests * chore: stash * chore: change import path to fix unit tests * chore: change import path to fix unit tests * chore: fix build --- .../hoc/withDynamicSchemaProps.test.tsx | 2 +- .../hooks/useSchemaSettingsRender.test.tsx | 2 +- packages/core/client/src/application/index.ts | 13 +- .../components/SchemaSettingsChildren.tsx | 4 +- .../schema-settings/context/index.ts | 10 - .../schema-settings/hooks/index.tsx | 10 - .../src/application/schema-settings/index.ts | 3 +- .../BlockSchemaComponentProvider.tsx | 3 + .../src/block-provider/CollectOperators.tsx | 71 ++++ .../block-provider/DetailsBlockProvider.tsx | 2 +- .../FilterFormBlockProvider.tsx | 20 +- .../src/block-provider/FormBlockProvider.tsx | 2 +- .../src/block-provider/TableBlockProvider.tsx | 2 +- .../block-provider/TableSelectorProvider.tsx | 2 +- .../__tests__/CollectOperators.test.tsx | 52 +++ .../client/src/block-provider/hooks/index.ts | 4 +- .../collection-field/CollectionField.tsx | 2 +- .../data-block/DataBlockProvider.tsx | 2 +- .../__tests__/transformToFilter.ts | 67 --- .../filter-provider/__tests__/useFilter.tsx | 63 --- .../core/client/src/filter-provider/utils.ts | 9 +- .../hoc/withDynamicSchemaProps.tsx | 4 +- packages/core/client/src/index.ts | 4 +- .../detailsWithPaginationSettings.tsx | 8 +- .../details-single/detailsBlockSettings.ts | 9 +- .../__tests__/fieldSettingsFormItem.test.tsx | 17 +- .../form/createFormBlockSettings.tsx | 2 +- .../data-blocks/form/editFormBlockSettings.ts | 2 +- .../grid-card/gridCardBlockSettings.ts | 2 +- .../data-blocks/list/listBlockSettings.ts | 3 +- .../data-blocks/table/tableBlockSettings.tsx | 24 +- .../collapse/filterCollapseBlockSettings.ts | 8 +- .../form/__e2e__/schemaSettings.test.ts | 82 +++- .../createFilterFormBlockSchema.test.ts | 2 - .../form/createFilterFormBlockSchema.ts | 2 - .../form/filterFormBlockSettings.ts | 9 +- .../form/hooks/useCollectOperator.ts | 30 ++ .../form/hooks/useFormItemProps.ts} | 6 +- .../antd/action/Action.Link.tsx | 4 +- .../schema-component/antd/action/Action.tsx | 2 +- .../antd/action/ActionBar.tsx | 4 +- .../AssociationFilter.BlockDesigner.tsx | 12 +- .../AssociationFilter.Item.tsx | 2 +- .../antd/auto-complete/AutoComplete.tsx | 2 +- .../antd/block-item/BlockItem.tsx | 2 +- .../antd/cascader/Cascader.tsx | 6 +- .../schema-component/antd/details/Details.tsx | 8 +- .../schema-component/antd/filter/Filter.tsx | 2 +- .../antd/filter/FilterAction.tsx | 2 +- .../antd/form-item/FormItem.tsx | 9 +- .../antd/form-item/SchemaSettingOptions.tsx | 75 +--- .../antd/form-v2/Form.Settings.tsx | 6 +- .../schema-component/antd/form-v2/Form.tsx | 2 +- .../antd/form/Form.Settings.tsx | 2 +- .../src/schema-component/antd/form/Form.tsx | 8 +- .../antd/grid-card/GridCard.Decorator.tsx | 4 +- .../antd/grid-card/GridCard.Designer.tsx | 2 +- .../antd/grid-card/GridCard.Item.tsx | 2 +- .../antd/grid-card/GridCard.tsx | 2 +- .../antd/list/List.Decorator.tsx | 2 +- .../antd/list/List.Designer.tsx | 8 +- .../schema-component/antd/list/List.Item.tsx | 2 +- .../src/schema-component/antd/list/List.tsx | 2 +- .../schema-component/antd/page/FixedBlock.tsx | 1 - .../antd/page/PageTabDesigner.tsx | 2 +- .../antd/pagination/index.tsx | 2 +- .../schema-component/antd/table-v2/Table.tsx | 2 +- .../antd/table-v2/TableBlockDesigner.tsx | 15 +- .../__tests__/Table.settings.test.tsx | 4 +- .../antd/table/Table.Void.Designer.tsx | 2 +- .../schema-component/antd/upload/Upload.tsx | 2 +- .../client/src/schema-initializer/utils.ts | 2 + .../DataTemplates/FormDataTemplates.tsx | 2 +- .../EnableChildCollections/index.tsx | 2 +- .../schema-settings/GeneralSchemaDesigner.tsx | 9 +- .../LinkageRules/LinkageRuleActionGroup.tsx | 4 +- .../schema-settings/LinkageRules/index.tsx | 2 +- .../src/schema-settings/SchemaSettings.tsx | 392 ++---------------- .../SchemaSettingsBlockTitleItem.tsx | 55 +++ .../SchemaSettingsConnectDataBlocks.tsx | 166 ++++++++ .../SchemaSettingsSortField.tsx | 61 +++ .../SchemaSettingsTemplate.tsx | 121 ++++++ .../core/client/src/schema-settings/index.ts | 13 +- .../src/client/block/MapBlock.Settings.tsx | 7 +- 84 files changed, 851 insertions(+), 746 deletions(-) delete mode 100644 packages/core/client/src/application/schema-settings/context/index.ts delete mode 100644 packages/core/client/src/application/schema-settings/hooks/index.tsx create mode 100644 packages/core/client/src/block-provider/CollectOperators.tsx create mode 100644 packages/core/client/src/block-provider/__tests__/CollectOperators.test.tsx delete mode 100644 packages/core/client/src/filter-provider/__tests__/transformToFilter.ts delete mode 100644 packages/core/client/src/filter-provider/__tests__/useFilter.tsx rename packages/core/client/src/{application => }/hoc/withDynamicSchemaProps.tsx (98%) create mode 100644 packages/core/client/src/modules/blocks/filter-blocks/form/hooks/useCollectOperator.ts rename packages/core/client/src/{application/hoc/index.ts => modules/blocks/filter-blocks/form/hooks/useFormItemProps.ts} (69%) create mode 100644 packages/core/client/src/schema-settings/SchemaSettingsBlockTitleItem.tsx create mode 100644 packages/core/client/src/schema-settings/SchemaSettingsConnectDataBlocks.tsx create mode 100644 packages/core/client/src/schema-settings/SchemaSettingsSortField.tsx create mode 100644 packages/core/client/src/schema-settings/SchemaSettingsTemplate.tsx diff --git a/packages/core/client/src/application/__tests__/hoc/withDynamicSchemaProps.test.tsx b/packages/core/client/src/application/__tests__/hoc/withDynamicSchemaProps.test.tsx index 7652b77e68df1..fa76a42e15956 100644 --- a/packages/core/client/src/application/__tests__/hoc/withDynamicSchemaProps.test.tsx +++ b/packages/core/client/src/application/__tests__/hoc/withDynamicSchemaProps.test.tsx @@ -9,8 +9,8 @@ import { render } from '@nocobase/test/client'; import React from 'react'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { SchemaComponent, SchemaComponentProvider } from '../../../schema-component'; -import { withDynamicSchemaProps } from '../../hoc'; const HelloComponent = withDynamicSchemaProps((props: any) => (
{JSON.stringify(props)}
diff --git a/packages/core/client/src/application/__tests__/schema-settings/hooks/useSchemaSettingsRender.test.tsx b/packages/core/client/src/application/__tests__/schema-settings/hooks/useSchemaSettingsRender.test.tsx index 630f29c163d04..3404d1d846724 100644 --- a/packages/core/client/src/application/__tests__/schema-settings/hooks/useSchemaSettingsRender.test.tsx +++ b/packages/core/client/src/application/__tests__/schema-settings/hooks/useSchemaSettingsRender.test.tsx @@ -7,9 +7,9 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import React from 'react'; import { Application, SchemaSettings, useSchemaSettingsRender } from '@nocobase/client'; import { render, screen, waitFor } from '@nocobase/test/client'; +import React from 'react'; describe('useSchemaSettingsRender', () => { async function createApp(DemoComponent: any) { diff --git a/packages/core/client/src/application/index.ts b/packages/core/client/src/application/index.ts index cac885b888f6d..63a51be8b8757 100644 --- a/packages/core/client/src/application/index.ts +++ b/packages/core/client/src/application/index.ts @@ -8,15 +8,16 @@ */ export * from './Application'; -export * from './hooks'; export * from './Plugin'; +export * from './PluginSettingsManager'; export * from './RouterManager'; -export * from './utils'; export * from './components'; +export { ApplicationContext } from './context'; +export * from './globalType'; +export * from './hooks'; export * from './schema-initializer'; export * from './schema-settings'; +export * from './schema-settings/context/SchemaSettingItemContext'; +export * from './schema-settings/hooks/useSchemaSettingsRender'; export * from './schema-toolbar'; -export * from './PluginSettingsManager'; -export * from './hoc'; -export { ApplicationContext } from './context'; -export * from './globalType'; +export * from './utils'; diff --git a/packages/core/client/src/application/schema-settings/components/SchemaSettingsChildren.tsx b/packages/core/client/src/application/schema-settings/components/SchemaSettingsChildren.tsx index 44e30815e367d..f80a135dcbfea 100644 --- a/packages/core/client/src/application/schema-settings/components/SchemaSettingsChildren.tsx +++ b/packages/core/client/src/application/schema-settings/components/SchemaSettingsChildren.tsx @@ -9,6 +9,7 @@ import React, { FC, memo, useEffect, useMemo, useRef } from 'react'; +import { useFieldComponentName } from '../../../common/useFieldComponentName'; import { useFindComponent } from '../../../schema-component'; import { SchemaSettingsActionModalItem, @@ -24,9 +25,8 @@ import { SchemaSettingsSwitchItem, useSchemaSettings, } from '../../../schema-settings/SchemaSettings'; -import { SchemaSettingItemContext } from '../context'; +import { SchemaSettingItemContext } from '../context/SchemaSettingItemContext'; import { SchemaSettingsItemType } from '../types'; -import { useFieldComponentName } from '../../../common/useFieldComponentName'; export interface SchemaSettingsChildrenProps { children: SchemaSettingsItemType[]; diff --git a/packages/core/client/src/application/schema-settings/context/index.ts b/packages/core/client/src/application/schema-settings/context/index.ts deleted file mode 100644 index d7f8c7e5740dc..0000000000000 --- a/packages/core/client/src/application/schema-settings/context/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * This file is part of the NocoBase (R) project. - * Copyright (c) 2020-2024 NocoBase Co., Ltd. - * Authors: NocoBase Team. - * - * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. - * For more information, please refer to: https://www.nocobase.com/agreement. - */ - -export * from './SchemaSettingItemContext'; diff --git a/packages/core/client/src/application/schema-settings/hooks/index.tsx b/packages/core/client/src/application/schema-settings/hooks/index.tsx deleted file mode 100644 index 11fe3de33dac3..0000000000000 --- a/packages/core/client/src/application/schema-settings/hooks/index.tsx +++ /dev/null @@ -1,10 +0,0 @@ -/** - * This file is part of the NocoBase (R) project. - * Copyright (c) 2020-2024 NocoBase Co., Ltd. - * Authors: NocoBase Team. - * - * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. - * For more information, please refer to: https://www.nocobase.com/agreement. - */ - -export * from './useSchemaSettingsRender'; diff --git a/packages/core/client/src/application/schema-settings/index.ts b/packages/core/client/src/application/schema-settings/index.ts index 30327ee6cf152..2b155a229d81c 100644 --- a/packages/core/client/src/application/schema-settings/index.ts +++ b/packages/core/client/src/application/schema-settings/index.ts @@ -9,7 +9,6 @@ export * from './SchemaSettings'; export * from './SchemaSettingsManager'; -export * from './hooks'; export * from './components'; -export * from './context'; +export * from './context/SchemaSettingItemContext'; export * from './types'; diff --git a/packages/core/client/src/block-provider/BlockSchemaComponentProvider.tsx b/packages/core/client/src/block-provider/BlockSchemaComponentProvider.tsx index 7e6b1c0665355..207dbd3f15fcb 100644 --- a/packages/core/client/src/block-provider/BlockSchemaComponentProvider.tsx +++ b/packages/core/client/src/block-provider/BlockSchemaComponentProvider.tsx @@ -31,6 +31,7 @@ import { CollapseItemSchemaToolbar } from '../modules/blocks/filter-blocks/colla import { useCollapseBlockDecoratorProps } from '../modules/blocks/filter-blocks/collapse/hooks/useCollapseBlockDecoratorProps'; import { useFilterFormBlockDecoratorProps } from '../modules/blocks/filter-blocks/form/hooks/useFilterFormBlockDecoratorProps'; import { useFilterFormBlockProps } from '../modules/blocks/filter-blocks/form/hooks/useFilterFormBlockProps'; +import { useFormItemProps } from '../modules/blocks/filter-blocks/form/hooks/useFormItemProps'; import { SchemaComponentOptions } from '../schema-component'; import { RecordLink, useParamsFromRecord, useSourceIdFromParentRecord, useSourceIdFromRecord } from './BlockProvider'; import { DetailsBlockProvider, useDetailsBlockProps } from './DetailsBlockProvider'; @@ -83,6 +84,7 @@ export const BlockSchemaComponentProvider: React.FC = (props) => { useFilterFormBlockProps, useFilterFormBlockDecoratorProps, useGridCardBlockDecoratorProps, + useFormItemProps, }} > {props.children} @@ -142,6 +144,7 @@ export class BlockSchemaComponentPlugin extends Plugin { useFilterFormBlockProps, useFilterFormBlockDecoratorProps, useGridCardBlockDecoratorProps, + useFormItemProps, }); } } diff --git a/packages/core/client/src/block-provider/CollectOperators.tsx b/packages/core/client/src/block-provider/CollectOperators.tsx new file mode 100644 index 0000000000000..a3355286eed69 --- /dev/null +++ b/packages/core/client/src/block-provider/CollectOperators.tsx @@ -0,0 +1,71 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import React, { FC, createContext, useCallback, useRef } from 'react'; + +const NOOP = () => {}; + +const CollectOperatorsContext = createContext<{ + /** 手机单个字段的操作符 */ + collectOperator: (name: string | number, operator: string) => void; + /** 获取所有字段的操作符 */ + getOperators: () => Record; + /** 获取单个字段的操作符 */ + getOperator: (name: string | number) => string; + /** 移除单个字段的操作符 */ + removeOperator: (name: string | number) => void; +}>(null); + +export const CollectOperators: FC<{ defaultOperators: Record }> = (props) => { + const operators = useRef(props.defaultOperators || {}); + + const collectOperator = useCallback((name: string, operator: string) => { + operators.current[name] = operator; + }, []); + + const getOperators = useCallback(() => { + return { ...operators.current }; + }, []); + + const getOperator = useCallback((name: string) => { + return operators.current[name]; + }, []); + + const removeOperator = useCallback((name: string) => { + delete operators.current[name]; + }, []); + + return ( + + {props.children} + + ); +}; + +export const useOperators = () => { + const { + getOperator = NOOP, + getOperators = NOOP, + collectOperator = NOOP, + removeOperator = NOOP, + } = React.useContext(CollectOperatorsContext) || {}; + return { + getOperator, + getOperators: getOperators as () => Record | undefined, + collectOperator, + removeOperator, + }; +}; diff --git a/packages/core/client/src/block-provider/DetailsBlockProvider.tsx b/packages/core/client/src/block-provider/DetailsBlockProvider.tsx index 9270a8b896112..55b44ce314d9b 100644 --- a/packages/core/client/src/block-provider/DetailsBlockProvider.tsx +++ b/packages/core/client/src/block-provider/DetailsBlockProvider.tsx @@ -11,10 +11,10 @@ import { createForm } from '@formily/core'; import { useField, useFieldSchema } from '@formily/react'; import { Spin } from 'antd'; import React, { createContext, useContext, useEffect, useMemo, useRef } from 'react'; -import { withDynamicSchemaProps } from '../application/hoc/withDynamicSchemaProps'; import { useCollectionManager_deprecated } from '../collection-manager'; import { useCollectionRecordData } from '../data-source'; import { useCollectionParentRecord } from '../data-source/collection-record/CollectionRecordProvider'; +import { withDynamicSchemaProps } from '../hoc/withDynamicSchemaProps'; import { useDetailsWithPaginationBlockParams } from '../modules/blocks/data-blocks/details-multi/hooks/useDetailsWithPaginationBlockParams'; import { RecordProvider } from '../record-provider'; import { useDesignable } from '../schema-component'; diff --git a/packages/core/client/src/block-provider/FilterFormBlockProvider.tsx b/packages/core/client/src/block-provider/FilterFormBlockProvider.tsx index 089267f642300..0c0bb304edb50 100644 --- a/packages/core/client/src/block-provider/FilterFormBlockProvider.tsx +++ b/packages/core/client/src/block-provider/FilterFormBlockProvider.tsx @@ -7,18 +7,26 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ +import { useFieldSchema } from '@formily/react'; import React from 'react'; +import { withDynamicSchemaProps } from '../hoc/withDynamicSchemaProps'; import { DatePickerProvider } from '../schema-component'; import { DefaultValueProvider } from '../schema-settings'; +import { CollectOperators } from './CollectOperators'; import { FormBlockProvider } from './FormBlockProvider'; -import { withDynamicSchemaProps } from '../application/hoc/withDynamicSchemaProps'; export const FilterFormBlockProvider = withDynamicSchemaProps((props) => { + const filedSchema = useFieldSchema(); + // 'x-filter-operators' 已被弃用,这里是为了兼容旧的配置 + const deprecatedOperators = filedSchema['x-filter-operators'] || {}; + return ( - - false}> - - - + + + false}> + + + + ); }); diff --git a/packages/core/client/src/block-provider/FormBlockProvider.tsx b/packages/core/client/src/block-provider/FormBlockProvider.tsx index a6fecd48b12b9..4b56b2e7278ea 100644 --- a/packages/core/client/src/block-provider/FormBlockProvider.tsx +++ b/packages/core/client/src/block-provider/FormBlockProvider.tsx @@ -11,13 +11,13 @@ import { createForm } from '@formily/core'; import { Schema, useField } from '@formily/react'; import { Spin } from 'antd'; import React, { createContext, useContext, useEffect, useMemo, useRef } from 'react'; -import { withDynamicSchemaProps } from '../application/hoc/withDynamicSchemaProps'; import { CollectionRecord, useCollectionManager, useCollectionParentRecordData, useCollectionRecord, } from '../data-source'; +import { withDynamicSchemaProps } from '../hoc/withDynamicSchemaProps'; import { useTreeParentRecord } from '../modules/blocks/data-blocks/table/TreeRecordProvider'; import { RecordProvider } from '../record-provider'; import { useActionContext } from '../schema-component'; diff --git a/packages/core/client/src/block-provider/TableBlockProvider.tsx b/packages/core/client/src/block-provider/TableBlockProvider.tsx index e5121a2653a2c..86432e8ae0234 100644 --- a/packages/core/client/src/block-provider/TableBlockProvider.tsx +++ b/packages/core/client/src/block-provider/TableBlockProvider.tsx @@ -10,8 +10,8 @@ import { createForm } from '@formily/core'; import { FormContext, useField, useFieldSchema } from '@formily/react'; import React, { createContext, useCallback, useContext, useMemo, useState } from 'react'; -import { withDynamicSchemaProps } from '../application/hoc/withDynamicSchemaProps'; import { useCollectionManager_deprecated } from '../collection-manager'; +import { withDynamicSchemaProps } from '../hoc/withDynamicSchemaProps'; import { useTableBlockParams } from '../modules/blocks/data-blocks/table'; import { FixedBlockWrapper, SchemaComponentOptions } from '../schema-component'; import { BlockProvider, useBlockRequestContext } from './BlockProvider'; diff --git a/packages/core/client/src/block-provider/TableSelectorProvider.tsx b/packages/core/client/src/block-provider/TableSelectorProvider.tsx index 7e6c38930e518..9732575cf1c4c 100644 --- a/packages/core/client/src/block-provider/TableSelectorProvider.tsx +++ b/packages/core/client/src/block-provider/TableSelectorProvider.tsx @@ -12,11 +12,11 @@ import { Schema, useField, useFieldSchema } from '@formily/react'; import _ from 'lodash'; import uniq from 'lodash/uniq'; import React, { createContext, useContext, useEffect, useState } from 'react'; -import { withDynamicSchemaProps } from '../application/hoc/withDynamicSchemaProps'; import { useCollectionManager_deprecated } from '../collection-manager'; import { useCollectionParentRecordData } from '../data-source/collection-record/CollectionRecordProvider'; import { isInFilterFormBlock } from '../filter-provider'; import { mergeFilter } from '../filter-provider/utils'; +import { withDynamicSchemaProps } from '../hoc/withDynamicSchemaProps'; import { RecordProvider, useRecord } from '../record-provider'; import { SchemaComponentOptions } from '../schema-component'; import { BlockProvider, useBlockRequestContext } from './BlockProvider'; diff --git a/packages/core/client/src/block-provider/__tests__/CollectOperators.test.tsx b/packages/core/client/src/block-provider/__tests__/CollectOperators.test.tsx new file mode 100644 index 0000000000000..a3628fb19b597 --- /dev/null +++ b/packages/core/client/src/block-provider/__tests__/CollectOperators.test.tsx @@ -0,0 +1,52 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import { render } from '@nocobase/test/client'; +import React from 'react'; +import { CollectOperators, useOperators } from '../CollectOperators'; + +describe('CollectOperators', () => { + it('should collect and get operators correctly', () => { + const defaultOperators = { + field1: 'operator1', + field2: 'operator2', + }; + + const TestComponent = () => { + const { collectOperator, getOperators, getOperator } = useOperators(); + + collectOperator('field3', 'operator3'); + + const operators = getOperators(); + const operator = getOperator('field1') as string; + + return ( +
+ {JSON.stringify(operators)} + {operator} +
+ ); + }; + + const { getByTestId } = render( + + + , + ); + + const operatorsElement = getByTestId('operators'); + const operatorElement = getByTestId('operator'); + + expect(JSON.parse(operatorsElement.textContent)).toEqual({ + ...defaultOperators, + field3: 'operator3', + }); + expect(operatorElement.textContent).toBe('operator1'); + }); +}); diff --git a/packages/core/client/src/block-provider/hooks/index.ts b/packages/core/client/src/block-provider/hooks/index.ts index 4e8c712034fa6..3e4fa92a77308 100644 --- a/packages/core/client/src/block-provider/hooks/index.ts +++ b/packages/core/client/src/block-provider/hooks/index.ts @@ -40,6 +40,7 @@ import { useLocalVariables, useVariables } from '../../variables'; import { isVariable } from '../../variables/utils/isVariable'; import { transformVariableValue } from '../../variables/utils/transformVariableValue'; import { useBlockRequestContext, useFilterByTk, useParamsFromRecord } from '../BlockProvider'; +import { useOperators } from '../CollectOperators'; import { useDetailsBlockContext } from '../DetailsBlockProvider'; import { TableFieldResource } from '../TableFieldProvider'; @@ -413,6 +414,7 @@ export const useFilterBlockActionProps = () => { const { getDataBlocks } = useFilterBlock(); const { name } = useCollection_deprecated(); const { getCollectionJoinField } = useCollectionManager_deprecated(); + const { getOperators } = useOperators(); actionField.data = actionField.data || {}; @@ -433,7 +435,7 @@ export const useFilterBlockActionProps = () => { const storedFilter = block.service.params?.[1]?.filters || {}; storedFilter[uid] = removeNullCondition( - transformToFilter(form.values, fieldSchema, getCollectionJoinField, name), + transformToFilter(form.values, getOperators(), getCollectionJoinField, name), ); const mergedFilter = mergeFilter([ diff --git a/packages/core/client/src/data-source/collection-field/CollectionField.tsx b/packages/core/client/src/data-source/collection-field/CollectionField.tsx index fe42188f22158..ee8193d86e50a 100644 --- a/packages/core/client/src/data-source/collection-field/CollectionField.tsx +++ b/packages/core/client/src/data-source/collection-field/CollectionField.tsx @@ -13,10 +13,10 @@ import { merge } from '@formily/shared'; import { concat } from 'lodash'; import React, { useCallback, useEffect, useMemo } from 'react'; import { useFormBlockContext } from '../../block-provider/FormBlockProvider'; +import { useDynamicComponentProps } from '../../hoc/withDynamicSchemaProps'; import { useCompile, useComponent } from '../../schema-component'; import { useIsAllowToSetDefaultValue } from '../../schema-settings/hooks/useIsAllowToSetDefaultValue'; import { CollectionFieldProvider, useCollectionField } from './CollectionFieldProvider'; -import { useDynamicComponentProps } from '../../application/hoc'; type Props = { component: any; diff --git a/packages/core/client/src/data-source/data-block/DataBlockProvider.tsx b/packages/core/client/src/data-source/data-block/DataBlockProvider.tsx index 3d9735366178e..939c9bf217f2a 100644 --- a/packages/core/client/src/data-source/data-block/DataBlockProvider.tsx +++ b/packages/core/client/src/data-source/data-block/DataBlockProvider.tsx @@ -11,7 +11,7 @@ import React, { FC, ReactNode, createContext, useContext, useMemo } from 'react' import { ACLCollectionProvider } from '../../acl/ACLProvider'; import { UseRequestOptions, UseRequestService } from '../../api-client'; -import { withDynamicSchemaProps } from '../../application/hoc'; +import { withDynamicSchemaProps } from '../../hoc/withDynamicSchemaProps'; import { Designable, useDesignable } from '../../schema-component'; import { AssociationProvider, diff --git a/packages/core/client/src/filter-provider/__tests__/transformToFilter.ts b/packages/core/client/src/filter-provider/__tests__/transformToFilter.ts deleted file mode 100644 index 12d355e72a3d2..0000000000000 --- a/packages/core/client/src/filter-provider/__tests__/transformToFilter.ts +++ /dev/null @@ -1,67 +0,0 @@ -/** - * This file is part of the NocoBase (R) project. - * Copyright (c) 2020-2024 NocoBase Co., Ltd. - * Authors: NocoBase Team. - * - * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. - * For more information, please refer to: https://www.nocobase.com/agreement. - */ - -import { transformToFilter } from '../utils'; - -// TODO: 前端测试报错解决之后,把该文件重命名为 transformToFilter.test.ts -describe('transformToFilter', () => { - it('should transform to filter', () => { - const values = { - name: 'name', - email: 'email', - user: { - name: 'name', - }, - list: [{ name: 'name1' }, { name: 'name2' }, { name: 'name3' }], - }; - - const fieldSchema = { - 'x-filter-operators': { - name: '$eq', - email: '$eq', - }, - }; - - const getField = (name: string) => { - if (name === 'user' || name === 'list') { - return { - targetKey: 'name', - }; - } - return { - targetKey: undefined, - }; - }; - - expect(transformToFilter(values, fieldSchema as any, getField)).toEqual({ - $and: [ - { - name: { - $eq: 'name', - }, - }, - { - email: { - $eq: 'email', - }, - }, - { - 'user.name': { - $eq: 'name', - }, - }, - { - 'list.name': { - $eq: ['name1', 'name2', 'name3'], - }, - }, - ], - }); - }); -}); diff --git a/packages/core/client/src/filter-provider/__tests__/useFilter.tsx b/packages/core/client/src/filter-provider/__tests__/useFilter.tsx deleted file mode 100644 index a1a25d9b9da1a..0000000000000 --- a/packages/core/client/src/filter-provider/__tests__/useFilter.tsx +++ /dev/null @@ -1,63 +0,0 @@ -/** - * This file is part of the NocoBase (R) project. - * Copyright (c) 2020-2024 NocoBase Co., Ltd. - * Authors: NocoBase Team. - * - * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. - * For more information, please refer to: https://www.nocobase.com/agreement. - */ - -import { render } from '@testing-library/react'; -import React from 'react'; -import { FilterBlockProvider, useFilterBlock } from '../FilterProvider'; - -describe('useFilter', () => { - test('should get a empty array', () => { - let getDataBlocks = null; - const Comp = () => { - ({ getDataBlocks } = useFilterBlock()); - return null; - }; - const App = () => { - return ( - - - - ); - }; - render(); - expect(getDataBlocks()).toEqual([]); - }); - - test('should not repeat', () => { - let getDataBlocks = null, - recordDataBlocks = null; - const Comp = () => { - ({ getDataBlocks, recordDataBlocks } = useFilterBlock()); - return null; - }; - const App = () => { - return ( - - - - ); - }; - render(); - - recordDataBlocks({ - name: 'test', - collection: {}, - doFilter: () => {}, - }); - expect(getDataBlocks().length).toBe(1); - - // avoid repeat - recordDataBlocks({ - name: 'test', - collection: {}, - doFilter: () => {}, - }); - expect(getDataBlocks().length).toBe(1); - }); -}); diff --git a/packages/core/client/src/filter-provider/utils.ts b/packages/core/client/src/filter-provider/utils.ts index 397f3996edb8d..74f068a8e5186 100644 --- a/packages/core/client/src/filter-provider/utils.ts +++ b/packages/core/client/src/filter-provider/utils.ts @@ -13,14 +13,13 @@ import _ from 'lodash'; import { useCallback, useEffect, useState } from 'react'; import { FilterTarget, findFilterTargets } from '../block-provider/hooks'; import { - Collection_deprecated, CollectionFieldOptions_deprecated, + Collection_deprecated, FieldOptions, - useCollection_deprecated, useCollectionManager_deprecated, + useCollection_deprecated, } from '../collection-manager'; import { removeNullCondition } from '../schema-component'; -import { findFilterOperators } from '../schema-component/antd/form-item/SchemaSettingOptions'; import { DataBlock, useFilterBlock } from './FilterProvider'; export enum FilterBlockType { @@ -99,12 +98,10 @@ export const useSupportedBlocks = (filterBlockType: FilterBlockType) => { export const transformToFilter = ( values: Record, - fieldSchema: Schema, + operators: Record, getCollectionJoinField: (name: string) => CollectionFieldOptions_deprecated, collectionName: string, ) => { - const { operators } = findFilterOperators(fieldSchema); - values = flatten(values, { breakOn({ value, path }) { // 下面操作符的值是一个数组,需要特殊处理 diff --git a/packages/core/client/src/application/hoc/withDynamicSchemaProps.tsx b/packages/core/client/src/hoc/withDynamicSchemaProps.tsx similarity index 98% rename from packages/core/client/src/application/hoc/withDynamicSchemaProps.tsx rename to packages/core/client/src/hoc/withDynamicSchemaProps.tsx index 635a3e9de9916..2bd0782dbc8c2 100644 --- a/packages/core/client/src/application/hoc/withDynamicSchemaProps.tsx +++ b/packages/core/client/src/hoc/withDynamicSchemaProps.tsx @@ -8,9 +8,9 @@ */ import { useExpressionScope } from '@formily/react'; -import React, { ComponentType, useMemo } from 'react'; -import { useDesignable } from '../../schema-component'; import _ from 'lodash'; +import React, { ComponentType, useMemo } from 'react'; +import { useDesignable } from '../schema-component'; const useDefaultDynamicComponentProps = () => undefined; diff --git a/packages/core/client/src/index.ts b/packages/core/client/src/index.ts index b3c6b0c6682da..84e299b89fa09 100644 --- a/packages/core/client/src/index.ts +++ b/packages/core/client/src/index.ts @@ -60,13 +60,13 @@ export * from './testUtils'; export * from './user'; export * from './variables'; -export { withDynamicSchemaProps } from './application/hoc/withDynamicSchemaProps'; +export { withDynamicSchemaProps } from './hoc/withDynamicSchemaProps'; export * from './modules/blocks/BlockSchemaToolbar'; export * from './modules/blocks/data-blocks/form'; export * from './modules/blocks/data-blocks/table'; export * from './modules/blocks/data-blocks/table-selector'; -export * from './modules/blocks/useParentRecordCommon'; export * from './modules/blocks/index'; +export * from './modules/blocks/useParentRecordCommon'; export { DeclareVariable } from './modules/variable/DeclareVariable'; diff --git a/packages/core/client/src/modules/blocks/data-blocks/details-multi/detailsWithPaginationSettings.tsx b/packages/core/client/src/modules/blocks/data-blocks/details-multi/detailsWithPaginationSettings.tsx index 42b99ceed764b..85d77798dd784 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/details-multi/detailsWithPaginationSettings.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/details-multi/detailsWithPaginationSettings.tsx @@ -16,12 +16,10 @@ import { useFormBlockContext } from '../../../../block-provider'; import { useDetailsBlockContext } from '../../../../block-provider/DetailsBlockProvider'; import { useCollection_deprecated, useSortFields } from '../../../../collection-manager'; import { removeNullCondition, useDesignable } from '../../../../schema-component'; -import { - SchemaSettingsBlockTitleItem, - SchemaSettingsTemplate, - SchemaSettingsLinkageRules, -} from '../../../../schema-settings'; +import { SchemaSettingsLinkageRules } from '../../../../schema-settings'; +import { SchemaSettingsBlockTitleItem } from '../../../../schema-settings/SchemaSettingsBlockTitleItem'; import { SchemaSettingsDataScope } from '../../../../schema-settings/SchemaSettingsDataScope'; +import { SchemaSettingsTemplate } from '../../../../schema-settings/SchemaSettingsTemplate'; import { setDataLoadingModeSettingsItem } from './setDataLoadingModeSettingsItem'; const commonItems: SchemaSettingsItemType[] = [ diff --git a/packages/core/client/src/modules/blocks/data-blocks/details-single/detailsBlockSettings.ts b/packages/core/client/src/modules/blocks/data-blocks/details-single/detailsBlockSettings.ts index 42974fba615c2..61dbaf54e041a 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/details-single/detailsBlockSettings.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/details-single/detailsBlockSettings.ts @@ -9,13 +9,10 @@ import { useFieldSchema } from '@formily/react'; import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings'; -import { useCollection_deprecated } from '../../../../collection-manager'; -import { - SchemaSettingsBlockTitleItem, - SchemaSettingsFormItemTemplate, - SchemaSettingsLinkageRules, -} from '../../../../schema-settings'; import { SchemaSettingsItemType } from '../../../../application/schema-settings/types'; +import { useCollection_deprecated } from '../../../../collection-manager'; +import { SchemaSettingsFormItemTemplate, SchemaSettingsLinkageRules } from '../../../../schema-settings'; +import { SchemaSettingsBlockTitleItem } from '../../../../schema-settings/SchemaSettingsBlockTitleItem'; const commonItems: SchemaSettingsItemType[] = [ { diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/__tests__/fieldSettingsFormItem.test.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/__tests__/fieldSettingsFormItem.test.tsx index 11fb3eadc8949..40d86440fa603 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/__tests__/fieldSettingsFormItem.test.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/form/__tests__/fieldSettingsFormItem.test.tsx @@ -7,20 +7,19 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ +import { useFieldSchema } from '@formily/react'; +import { observer } from '@formily/reactive-react'; +import { FilterFormBlockProvider, FormBlockProvider, FormItem, fieldSettingsFormItem } from '@nocobase/client'; import { - screen, + checkFieldTitle, checkSettings, + renderReadPrettySettings, + renderSettings, renderSingleSettings, - waitFor, + screen, userEvent, - renderReadPrettySingleSettings, - renderSettings, - renderReadPrettySettings, - checkFieldTitle, + waitFor, } from '@nocobase/test/client'; -import { FilterFormBlockProvider, FormBlockProvider, FormItem, fieldSettingsFormItem } from '@nocobase/client'; -import { useFieldSchema } from '@formily/react'; -import { observer } from '@formily/reactive-react'; import React from 'react'; describe('FieldSettingsFormItem', () => { diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/createFormBlockSettings.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/createFormBlockSettings.tsx index 27534d7601bfe..9a2b3b9cefaa6 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/createFormBlockSettings.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/form/createFormBlockSettings.tsx @@ -12,11 +12,11 @@ import { SchemaSettings } from '../../../../application/schema-settings/SchemaSe import { useFormBlockContext } from '../../../../block-provider'; import { useCollection_deprecated } from '../../../../collection-manager'; import { - SchemaSettingsBlockTitleItem, SchemaSettingsDataTemplates, SchemaSettingsFormItemTemplate, SchemaSettingsLinkageRules, } from '../../../../schema-settings'; +import { SchemaSettingsBlockTitleItem } from '../../../../schema-settings/SchemaSettingsBlockTitleItem'; export const createFormBlockSettings = new SchemaSettings({ name: 'blockSettings:createForm', diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/editFormBlockSettings.ts b/packages/core/client/src/modules/blocks/data-blocks/form/editFormBlockSettings.ts index 81c23db1faf1e..0b6e027e8cac9 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/editFormBlockSettings.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/form/editFormBlockSettings.ts @@ -12,11 +12,11 @@ import { SchemaSettings } from '../../../../application/schema-settings/SchemaSe import { useFormBlockContext } from '../../../../block-provider'; import { useCollection_deprecated } from '../../../../collection-manager'; import { - SchemaSettingsBlockTitleItem, SchemaSettingsDataTemplates, SchemaSettingsFormItemTemplate, SchemaSettingsLinkageRules, } from '../../../../schema-settings'; +import { SchemaSettingsBlockTitleItem } from '../../../../schema-settings/SchemaSettingsBlockTitleItem'; export const editFormBlockSettings = new SchemaSettings({ name: 'blockSettings:editForm', diff --git a/packages/core/client/src/modules/blocks/data-blocks/grid-card/gridCardBlockSettings.ts b/packages/core/client/src/modules/blocks/data-blocks/grid-card/gridCardBlockSettings.ts index 3fed6d27adb9a..6b138b5b2976e 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/grid-card/gridCardBlockSettings.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/grid-card/gridCardBlockSettings.ts @@ -17,8 +17,8 @@ import { useFormBlockContext } from '../../../../block-provider'; import { useCollection_deprecated, useSortFields } from '../../../../collection-manager'; import { removeNullCondition, useDesignable } from '../../../../schema-component'; import { pageSizeOptions } from '../../../../schema-component/antd/grid-card/options'; -import { SchemaSettingsTemplate } from '../../../../schema-settings'; import { SchemaSettingsDataScope } from '../../../../schema-settings/SchemaSettingsDataScope'; +import { SchemaSettingsTemplate } from '../../../../schema-settings/SchemaSettingsTemplate'; import { setDataLoadingModeSettingsItem } from '../details-multi/setDataLoadingModeSettingsItem'; import { SetTheCountOfColumnsDisplayedInARow } from './SetTheCountOfColumnsDisplayedInARow'; diff --git a/packages/core/client/src/modules/blocks/data-blocks/list/listBlockSettings.ts b/packages/core/client/src/modules/blocks/data-blocks/list/listBlockSettings.ts index fdc1bac618d58..2827b94f7a696 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/list/listBlockSettings.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/list/listBlockSettings.ts @@ -15,8 +15,9 @@ import { SchemaSettings } from '../../../../application/schema-settings/SchemaSe import { useFormBlockContext } from '../../../../block-provider'; import { useCollection_deprecated, useSortFields } from '../../../../collection-manager'; import { removeNullCondition, useDesignable } from '../../../../schema-component'; -import { SchemaSettingsBlockTitleItem, SchemaSettingsTemplate } from '../../../../schema-settings'; +import { SchemaSettingsBlockTitleItem } from '../../../../schema-settings/SchemaSettingsBlockTitleItem'; import { SchemaSettingsDataScope } from '../../../../schema-settings/SchemaSettingsDataScope'; +import { SchemaSettingsTemplate } from '../../../../schema-settings/SchemaSettingsTemplate'; import { setDataLoadingModeSettingsItem } from '../details-multi/setDataLoadingModeSettingsItem'; export const listBlockSettings = new SchemaSettings({ diff --git a/packages/core/client/src/modules/blocks/data-blocks/table/tableBlockSettings.tsx b/packages/core/client/src/modules/blocks/data-blocks/table/tableBlockSettings.tsx index ec8ee6d3d6743..9ed8c93bc87b7 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/table/tableBlockSettings.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/table/tableBlockSettings.tsx @@ -7,29 +7,27 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ +import { ArrayItems } from '@formily/antd-v5'; import { ISchema } from '@formily/json-schema'; import { useField, useFieldSchema } from '@formily/react'; +import { useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; import { useAPIClient } from '../../../../api-client'; -import { useTableBlockContext, useFormBlockContext } from '../../../../block-provider'; +import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings'; +import { useFormBlockContext, useTableBlockContext } from '../../../../block-provider'; import { useCollectionManager_deprecated, useCollection_deprecated, useSortFields, } from '../../../../collection-manager'; import { FilterBlockType } from '../../../../filter-provider/utils'; -import { useDesignable, removeNullCondition } from '../../../../schema-component'; -import { - SchemaSettingsBlockTitleItem, - SchemaSettingsSortField, - SchemaSettingsConnectDataBlocks, - SchemaSettingsTemplate, -} from '../../../../schema-settings/SchemaSettings'; -import { SchemaSettingsDataScope } from '../../../../schema-settings/SchemaSettingsDataScope'; -import { useCallback } from 'react'; -import { useTranslation } from 'react-i18next'; -import { ArrayItems } from '@formily/antd-v5'; +import { removeNullCondition, useDesignable } from '../../../../schema-component'; import { FixedBlockDesignerItem } from '../../../../schema-component/antd/page/FixedBlockDesignerItem'; -import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings'; +import { SchemaSettingsBlockTitleItem } from '../../../../schema-settings/SchemaSettingsBlockTitleItem'; +import { SchemaSettingsConnectDataBlocks } from '../../../../schema-settings/SchemaSettingsConnectDataBlocks'; +import { SchemaSettingsDataScope } from '../../../../schema-settings/SchemaSettingsDataScope'; +import { SchemaSettingsSortField } from '../../../../schema-settings/SchemaSettingsSortField'; +import { SchemaSettingsTemplate } from '../../../../schema-settings/SchemaSettingsTemplate'; import { setDataLoadingModeSettingsItem } from '../details-multi/setDataLoadingModeSettingsItem'; export const tableBlockSettings = new SchemaSettings({ diff --git a/packages/core/client/src/modules/blocks/filter-blocks/collapse/filterCollapseBlockSettings.ts b/packages/core/client/src/modules/blocks/filter-blocks/collapse/filterCollapseBlockSettings.ts index eeeb817dcf414..cd0aefa7578a9 100644 --- a/packages/core/client/src/modules/blocks/filter-blocks/collapse/filterCollapseBlockSettings.ts +++ b/packages/core/client/src/modules/blocks/filter-blocks/collapse/filterCollapseBlockSettings.ts @@ -12,11 +12,9 @@ import { useTranslation } from 'react-i18next'; import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings'; import { useCollection_deprecated } from '../../../../collection-manager'; import { FilterBlockType } from '../../../../filter-provider'; -import { - SchemaSettingsBlockTitleItem, - SchemaSettingsConnectDataBlocks, - SchemaSettingsTemplate, -} from '../../../../schema-settings'; +import { SchemaSettingsBlockTitleItem } from '../../../../schema-settings/SchemaSettingsBlockTitleItem'; +import { SchemaSettingsConnectDataBlocks } from '../../../../schema-settings/SchemaSettingsConnectDataBlocks'; +import { SchemaSettingsTemplate } from '../../../../schema-settings/SchemaSettingsTemplate'; export const filterCollapseBlockSettings = new SchemaSettings({ name: 'blockSettings:filterCollapse', diff --git a/packages/core/client/src/modules/blocks/filter-blocks/form/__e2e__/schemaSettings.test.ts b/packages/core/client/src/modules/blocks/filter-blocks/form/__e2e__/schemaSettings.test.ts index 06b5a39e530f9..1ec219beb86f9 100644 --- a/packages/core/client/src/modules/blocks/filter-blocks/form/__e2e__/schemaSettings.test.ts +++ b/packages/core/client/src/modules/blocks/filter-blocks/form/__e2e__/schemaSettings.test.ts @@ -36,7 +36,12 @@ test.describe('filter block schema settings', () => { }); test.describe('connect data blocks', () => { - test('connecting two blocks of the same collection', async ({ page, mockPage, mockRecords }) => { + test('connecting two blocks of the same collection', async ({ + page, + mockPage, + mockRecords, + clearBlockTemplates, + }) => { const nocoPage = await mockPage(oneFormAndOneTableWithSameCollection).waitForInit(); const records = await mockRecords('general', 3); await nocoPage.goto(); @@ -81,6 +86,81 @@ test.describe('filter block schema settings', () => { await expect( page.getByLabel('block-item-CardItem-general-table').getByRole('row', { name: records[0].singleLineText }), ).toBeVisible(); + + // 更改操作符为 “is not” + await page.getByLabel('block-item-CollectionField-').hover(); + await page.getByLabel('designer-schema-settings-CollectionField-FormItem.FilterFormDesigner-general-').hover(); + await page.getByRole('menuitem', { name: 'Operator contains' }).click(); + await page.getByRole('option', { name: 'is not', exact: true }).click(); + + // 输入值,点击筛选按钮 + await page + .getByLabel('block-item-CollectionField-general-filter-form-general.singleLineText-singleLineText') + .getByRole('textbox') + .click(); + await page + .getByLabel('block-item-CollectionField-general-filter-form-general.singleLineText-singleLineText') + .getByRole('textbox') + .fill(records[0].singleLineText); + + // 点击筛选按钮 + await page.getByLabel('action-Action-Filter records-submit-general-filter-form').click(); + + await expect( + page.getByLabel('block-item-CardItem-general-table').getByRole('row', { name: records[1].singleLineText }), + ).toBeVisible(); + await expect( + page.getByLabel('block-item-CardItem-general-table').getByRole('row', { name: records[2].singleLineText }), + ).toBeVisible(); + await expect( + page.getByLabel('block-item-CardItem-general-table').getByRole('row', { name: records[0].singleLineText }), + ).toBeHidden(); + + // 点击重置按钮 + await page.getByLabel('action-Action-Reset records-general-filter-form').click(); + + // 将筛选表单区块保存为模板 + await page.getByLabel('block-item-CardItem-general-filter-form').hover(); + await page.getByLabel('designer-schema-settings-CardItem-FormV2.FilterDesigner-general').hover(); + await page.getByRole('menuitem', { name: 'Save as block template' }).click(); + await page.getByRole('button', { name: 'OK', exact: true }).click(); + + // 输入值,点击筛选按钮 + await page + .getByLabel('block-item-CollectionField-general-filter-form-general.singleLineText-singleLineText') + .getByRole('textbox') + .click(); + await page + .getByLabel('block-item-CollectionField-general-filter-form-general.singleLineText-singleLineText') + .getByRole('textbox') + .fill(records[0].singleLineText); + + // 点击筛选按钮 + await page.getByLabel('action-Action-Filter records-submit-general-filter-form').click(); + + await expect( + page.getByLabel('block-item-CardItem-general-table').getByRole('row', { name: records[1].singleLineText }), + ).toBeVisible(); + await expect( + page.getByLabel('block-item-CardItem-general-table').getByRole('row', { name: records[2].singleLineText }), + ).toBeVisible(); + await expect( + page.getByLabel('block-item-CardItem-general-table').getByRole('row', { name: records[0].singleLineText }), + ).toBeHidden(); + + // 点击重置按钮 + await page.getByLabel('action-Action-Reset records-general-filter-form').click(); + await expect( + page.getByLabel('block-item-CardItem-general-table').getByRole('row', { name: records[1].singleLineText }), + ).toBeVisible(); + await expect( + page.getByLabel('block-item-CardItem-general-table').getByRole('row', { name: records[2].singleLineText }), + ).toBeVisible(); + await expect( + page.getByLabel('block-item-CardItem-general-table').getByRole('row', { name: records[0].singleLineText }), + ).toBeVisible(); + + await clearBlockTemplates(); }); }); }); diff --git a/packages/core/client/src/modules/blocks/filter-blocks/form/__tests__/createFilterFormBlockSchema.test.ts b/packages/core/client/src/modules/blocks/filter-blocks/form/__tests__/createFilterFormBlockSchema.test.ts index dafcb383b7894..2b6ee20b5cea0 100644 --- a/packages/core/client/src/modules/blocks/filter-blocks/form/__tests__/createFilterFormBlockSchema.test.ts +++ b/packages/core/client/src/modules/blocks/filter-blocks/form/__tests__/createFilterFormBlockSchema.test.ts @@ -55,7 +55,6 @@ describe('createFilterFormBlockSchema', () => { "collection": "myCollection", "dataSource": "myDataSource", }, - "x-filter-operators": {}, "x-filter-targets": [], "x-settings": "blockSettings:filterForm", "x-toolbar": "BlockSchemaToolbar", @@ -104,7 +103,6 @@ describe('createFilterFormBlockSchema', () => { "collection": "myCollection", "dataSource": "myDataSource", }, - "x-filter-operators": {}, "x-filter-targets": [], "x-settings": "blockSettings:filterForm", "x-toolbar": "BlockSchemaToolbar", diff --git a/packages/core/client/src/modules/blocks/filter-blocks/form/createFilterFormBlockSchema.ts b/packages/core/client/src/modules/blocks/filter-blocks/form/createFilterFormBlockSchema.ts index 16924f5c20a87..4f67888d8387f 100644 --- a/packages/core/client/src/modules/blocks/filter-blocks/form/createFilterFormBlockSchema.ts +++ b/packages/core/client/src/modules/blocks/filter-blocks/form/createFilterFormBlockSchema.ts @@ -34,8 +34,6 @@ export const createFilterFormBlockSchema = (options: { 'x-component': 'CardItem', // 保存当前筛选区块所能过滤的数据区块 'x-filter-targets': [], - // 用于存储用户设置的每个字段的运算符,目前仅筛选表单区块支持自定义 - 'x-filter-operators': {}, properties: { [uid()]: { type: 'void', diff --git a/packages/core/client/src/modules/blocks/filter-blocks/form/filterFormBlockSettings.ts b/packages/core/client/src/modules/blocks/filter-blocks/form/filterFormBlockSettings.ts index 9bda08eef0e91..68a8ed16f215f 100644 --- a/packages/core/client/src/modules/blocks/filter-blocks/form/filterFormBlockSettings.ts +++ b/packages/core/client/src/modules/blocks/filter-blocks/form/filterFormBlockSettings.ts @@ -12,12 +12,9 @@ import { useTranslation } from 'react-i18next'; import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings'; import { useCollection_deprecated } from '../../../../collection-manager'; import { FilterBlockType } from '../../../../filter-provider'; -import { - SchemaSettingsBlockTitleItem, - SchemaSettingsConnectDataBlocks, - SchemaSettingsFormItemTemplate, - SchemaSettingsLinkageRules, -} from '../../../../schema-settings'; +import { SchemaSettingsFormItemTemplate, SchemaSettingsLinkageRules } from '../../../../schema-settings'; +import { SchemaSettingsBlockTitleItem } from '../../../../schema-settings/SchemaSettingsBlockTitleItem'; +import { SchemaSettingsConnectDataBlocks } from '../../../../schema-settings/SchemaSettingsConnectDataBlocks'; export const filterFormBlockSettings = new SchemaSettings({ name: 'blockSettings:filterForm', diff --git a/packages/core/client/src/modules/blocks/filter-blocks/form/hooks/useCollectOperator.ts b/packages/core/client/src/modules/blocks/filter-blocks/form/hooks/useCollectOperator.ts new file mode 100644 index 0000000000000..d38afd1787b18 --- /dev/null +++ b/packages/core/client/src/modules/blocks/filter-blocks/form/hooks/useCollectOperator.ts @@ -0,0 +1,30 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import { useFieldSchema } from '@formily/react'; +import { useEffect } from 'react'; +import { useOperators } from '../../../../../block-provider/CollectOperators'; + +/** + * 用于将筛选表单中的字段操作符收集到一起 + */ +export const useCollectOperator = () => { + const fieldSchema = useFieldSchema(); + const { collectOperator, removeOperator } = useOperators(); + + useEffect(() => { + return () => { + removeOperator(fieldSchema.name); + }; + }, [fieldSchema.name, removeOperator]); + + if (fieldSchema['x-filter-operator']) { + collectOperator(fieldSchema.name, fieldSchema['x-filter-operator']); + } +}; diff --git a/packages/core/client/src/application/hoc/index.ts b/packages/core/client/src/modules/blocks/filter-blocks/form/hooks/useFormItemProps.ts similarity index 69% rename from packages/core/client/src/application/hoc/index.ts rename to packages/core/client/src/modules/blocks/filter-blocks/form/hooks/useFormItemProps.ts index 7e0130d3cf645..eeaf65737835f 100644 --- a/packages/core/client/src/application/hoc/index.ts +++ b/packages/core/client/src/modules/blocks/filter-blocks/form/hooks/useFormItemProps.ts @@ -7,4 +7,8 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -export * from './withDynamicSchemaProps'; +import { useCollectOperator } from './useCollectOperator'; + +export const useFormItemProps = () => { + useCollectOperator(); +}; diff --git a/packages/core/client/src/schema-component/antd/action/Action.Link.tsx b/packages/core/client/src/schema-component/antd/action/Action.Link.tsx index 19178d1a5edc2..6c677828767a5 100644 --- a/packages/core/client/src/schema-component/antd/action/Action.Link.tsx +++ b/packages/core/client/src/schema-component/antd/action/Action.Link.tsx @@ -8,11 +8,11 @@ */ import { observer } from '@formily/react'; -import React from 'react'; import classnames from 'classnames'; +import React from 'react'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import Action from './Action'; import { ComposedAction } from './types'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; export const ActionLink: ComposedAction = withDynamicSchemaProps( observer((props: any) => { diff --git a/packages/core/client/src/schema-component/antd/action/Action.tsx b/packages/core/client/src/schema-component/antd/action/Action.tsx index 9d5ddc1814e70..c6c01278343bd 100644 --- a/packages/core/client/src/schema-component/antd/action/Action.tsx +++ b/packages/core/client/src/schema-component/antd/action/Action.tsx @@ -17,13 +17,13 @@ import { useTranslation } from 'react-i18next'; import { StablePopover, useActionContext } from '../..'; import { useDesignable } from '../../'; import { useACLActionParamsContext } from '../../../acl'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; import { useCollection, useCollectionParentRecordData, useCollectionRecordData, useDataBlockRequest, } from '../../../data-source'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { Icon } from '../../../icon'; import { TreeRecordProvider } from '../../../modules/blocks/data-blocks/table/TreeRecordProvider'; import { DeclareVariable } from '../../../modules/variable/DeclareVariable'; diff --git a/packages/core/client/src/schema-component/antd/action/ActionBar.tsx b/packages/core/client/src/schema-component/antd/action/ActionBar.tsx index bf06ff2ba41a0..398b2ea43e750 100644 --- a/packages/core/client/src/schema-component/antd/action/ActionBar.tsx +++ b/packages/core/client/src/schema-component/antd/action/ActionBar.tsx @@ -12,10 +12,10 @@ import { RecursionField, observer, useFieldSchema } from '@formily/react'; import { Space, SpaceProps } from 'antd'; import React, { CSSProperties, useContext } from 'react'; import { createPortal } from 'react-dom'; +import { useSchemaInitializerRender } from '../../../application'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { DndContext } from '../../common'; import { useDesignable, useProps } from '../../hooks'; -import { useSchemaInitializerRender } from '../../../application'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; export interface ActionBarProps { layout?: 'one-column' | 'two-columns'; diff --git a/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.BlockDesigner.tsx b/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.BlockDesigner.tsx index e19ba0011e22f..95df01c582890 100644 --- a/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.BlockDesigner.tsx +++ b/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.BlockDesigner.tsx @@ -12,14 +12,10 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { useCollection_deprecated } from '../../../collection-manager'; import { FilterBlockType } from '../../../filter-provider/utils'; -import { - GeneralSchemaDesigner, - SchemaSettingsBlockTitleItem, - SchemaSettingsConnectDataBlocks, - SchemaSettingsDivider, - SchemaSettingsRemove, - SchemaSettingsTemplate, -} from '../../../schema-settings'; +import { GeneralSchemaDesigner, SchemaSettingsDivider, SchemaSettingsRemove } from '../../../schema-settings'; +import { SchemaSettingsBlockTitleItem } from '../../../schema-settings/SchemaSettingsBlockTitleItem'; +import { SchemaSettingsConnectDataBlocks } from '../../../schema-settings/SchemaSettingsConnectDataBlocks'; +import { SchemaSettingsTemplate } from '../../../schema-settings/SchemaSettingsTemplate'; import { useSchemaTemplate } from '../../../schema-templates'; export const AssociationFilterBlockDesigner = () => { diff --git a/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.Item.tsx b/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.Item.tsx index 6d6e816a7225d..4f2cb7a96b38b 100644 --- a/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.Item.tsx +++ b/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.Item.tsx @@ -12,6 +12,7 @@ import { useFieldSchema } from '@formily/react'; import { Col, Collapse, Input, Row, Tree } from 'antd'; import cls from 'classnames'; import React, { ChangeEvent, MouseEvent, useMemo, useState } from 'react'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { SortableItem } from '../../common'; import { useCompile, useDesigner, useProps } from '../../hooks'; import { useToken } from '../__builtins__'; @@ -19,7 +20,6 @@ import { EllipsisWithTooltip } from '../input'; import { getLabelFormatValue, useLabelUiSchema } from '../record-picker'; import { AssociationFilter } from './AssociationFilter'; import useStyles from './AssociationFilter.Item.style'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; const { Panel } = Collapse; diff --git a/packages/core/client/src/schema-component/antd/auto-complete/AutoComplete.tsx b/packages/core/client/src/schema-component/antd/auto-complete/AutoComplete.tsx index f3737ae320cbd..59c18f580ba1f 100644 --- a/packages/core/client/src/schema-component/antd/auto-complete/AutoComplete.tsx +++ b/packages/core/client/src/schema-component/antd/auto-complete/AutoComplete.tsx @@ -9,8 +9,8 @@ import { connect, mapProps, mapReadPretty } from '@formily/react'; import { AutoComplete as AntdAutoComplete } from 'antd'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { ReadPretty } from '../input'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; export const AutoComplete = withDynamicSchemaProps( connect( diff --git a/packages/core/client/src/schema-component/antd/block-item/BlockItem.tsx b/packages/core/client/src/schema-component/antd/block-item/BlockItem.tsx index 5c4c67b6e9452..acc5c305494e7 100644 --- a/packages/core/client/src/schema-component/antd/block-item/BlockItem.tsx +++ b/packages/core/client/src/schema-component/antd/block-item/BlockItem.tsx @@ -10,7 +10,7 @@ import { useFieldSchema } from '@formily/react'; import cls from 'classnames'; import React, { useMemo } from 'react'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { CustomCreateStylesUtils, createStyles } from '../../../style'; import { SortableItem } from '../../common'; import { useDesigner, useProps } from '../../hooks'; diff --git a/packages/core/client/src/schema-component/antd/cascader/Cascader.tsx b/packages/core/client/src/schema-component/antd/cascader/Cascader.tsx index 1af46216090e5..3de48cff1bd5e 100644 --- a/packages/core/client/src/schema-component/antd/cascader/Cascader.tsx +++ b/packages/core/client/src/schema-component/antd/cascader/Cascader.tsx @@ -11,14 +11,14 @@ import { LoadingOutlined } from '@ant-design/icons'; import { ArrayField } from '@formily/core'; import { connect, mapProps, mapReadPretty, useField } from '@formily/react'; import { toArr } from '@formily/shared'; -import { Cascader as AntdCascader, Space, CascaderProps as AntdCascaderProps } from 'antd'; +import { Cascader as AntdCascader, CascaderProps as AntdCascaderProps, Space } from 'antd'; +import { BaseOptionType } from 'antd/es/select'; import { isBoolean, omit } from 'lodash'; import React from 'react'; import { UseRequestResult, useRequest } from '../../../api-client'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { ReadPretty } from './ReadPretty'; import { defaultFieldNames } from './defaultFieldNames'; -import { BaseOptionType } from 'antd/es/select'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; const useDefDataSource = (options, props: any) => { const field = useField(); diff --git a/packages/core/client/src/schema-component/antd/details/Details.tsx b/packages/core/client/src/schema-component/antd/details/Details.tsx index aa607e3788222..13e09f5d29a49 100644 --- a/packages/core/client/src/schema-component/antd/details/Details.tsx +++ b/packages/core/client/src/schema-component/antd/details/Details.tsx @@ -7,12 +7,12 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import React from 'react'; -import { FormV2 } from '../form-v2'; -import _ from 'lodash'; import { Empty } from 'antd'; +import _ from 'lodash'; +import React from 'react'; import { useDataBlockRequest } from '../../../data-source'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; +import { FormV2 } from '../form-v2'; import { FormProps } from '../form-v2/Form'; export type DetailsProps = FormProps; diff --git a/packages/core/client/src/schema-component/antd/filter/Filter.tsx b/packages/core/client/src/schema-component/antd/filter/Filter.tsx index f754a96b8724f..89d6900348f43 100644 --- a/packages/core/client/src/schema-component/antd/filter/Filter.tsx +++ b/packages/core/client/src/schema-component/antd/filter/Filter.tsx @@ -11,13 +11,13 @@ import { ObjectField as ObjectFieldModel } from '@formily/core'; import { observer, useField, useFieldSchema } from '@formily/react'; import React, { useEffect } from 'react'; import { UseRequestOptions, useRequest } from '../../../api-client'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { useProps } from '../../hooks/useProps'; import { FilterActionDesigner } from './Filter.Action.Designer'; import { FilterAction } from './FilterAction'; import { FilterGroup } from './FilterGroup'; import { SaveDefaultValue } from './SaveDefaultValue'; import { FilterContext, FilterContextProps } from './context'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; const useDef = (options: UseRequestOptions) => { const field = useField(); diff --git a/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx b/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx index 418f11cd7ae65..487978f518d05 100644 --- a/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx +++ b/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx @@ -14,12 +14,12 @@ import { flatten, unflatten } from '@nocobase/utils/client'; import { Button, Space } from 'antd'; import React, { createContext, useCallback, useContext, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { FormProvider, SchemaComponent } from '../../core'; import { useDesignable } from '../../hooks'; import { useProps } from '../../hooks/useProps'; import { Action, ActionProps } from '../action'; import { StablePopover } from '../popover'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; export const FilterActionContext = createContext(null); FilterActionContext.displayName = 'FilterActionContext'; diff --git a/packages/core/client/src/schema-component/antd/form-item/FormItem.tsx b/packages/core/client/src/schema-component/antd/form-item/FormItem.tsx index c72ad4563fef7..c4055e3221e55 100644 --- a/packages/core/client/src/schema-component/antd/form-item/FormItem.tsx +++ b/packages/core/client/src/schema-component/antd/form-item/FormItem.tsx @@ -11,12 +11,13 @@ import { css, cx } from '@emotion/css'; import { IFormItemProps, FormItem as Item } from '@formily/antd-v5'; import { Field } from '@formily/core'; import { observer, useField, useFieldSchema } from '@formily/react'; -import React, { FC, useEffect, useMemo } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { ACLCollectionFieldProvider } from '../../../acl/ACLProvider'; import { useApp } from '../../../application'; import { useFormActiveFields } from '../../../block-provider/hooks/useFormActiveFields'; import { Collection_deprecated } from '../../../collection-manager'; import { CollectionFieldProvider } from '../../../data-source/collection-field/CollectionFieldProvider'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { GeneralSchemaDesigner } from '../../../schema-settings'; import { useVariables } from '../../../variables'; import useContextVariable from '../../../variables/hooks/useContextVariable'; @@ -41,8 +42,8 @@ const formItemLabelCss = css` } `; -export const FormItem: any = observer( - (props: IFormItemProps) => { +export const FormItem: any = withDynamicSchemaProps( + observer((props: IFormItemProps) => { useEnsureOperatorsValid(); const field = useField(); const schema = useFieldSchema(); @@ -89,7 +90,7 @@ export const FormItem: any = observer( ); - }, + }), { displayName: 'FormItem' }, ); diff --git a/packages/core/client/src/schema-component/antd/form-item/SchemaSettingOptions.tsx b/packages/core/client/src/schema-component/antd/form-item/SchemaSettingOptions.tsx index bc5a8999a5dee..a601e052247ca 100644 --- a/packages/core/client/src/schema-component/antd/form-item/SchemaSettingOptions.tsx +++ b/packages/core/client/src/schema-component/antd/form-item/SchemaSettingOptions.tsx @@ -9,40 +9,18 @@ import { ArrayCollapse, FormLayout } from '@formily/antd-v5'; import { Field } from '@formily/core'; -import { ISchema, Schema, useField, useFieldSchema } from '@formily/react'; -import { uid } from '@formily/shared'; +import { ISchema, useField, useFieldSchema } from '@formily/react'; import _ from 'lodash'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { useFormBlockContext } from '../../../block-provider'; -import { useCollection_deprecated, useCollectionManager_deprecated } from '../../../collection-manager'; +import { useOperators } from '../../../block-provider/CollectOperators'; +import { useCollectionManager_deprecated, useCollection_deprecated } from '../../../collection-manager'; import { SchemaSettingsModalItem, SchemaSettingsSelectItem, SchemaSettingsSwitchItem } from '../../../schema-settings'; import { isPatternDisabled } from '../../../schema-settings/isPatternDisabled'; 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']) { - return { - operators: schema['x-filter-operators'], - uid: schema['x-uid'], - }; - } - schema = schema.parent; - } - return {}; -}; - -const divWrap = (schema: ISchema) => { - return { - type: 'void', - 'x-component': 'div', - properties: { - [schema.name || uid()]: schema, - }, - }; -}; export const EditTitle = () => { const { getCollectionJoinField } = useCollectionManager_deprecated(); @@ -496,10 +474,11 @@ export const EditPattern = () => { export const useEnsureOperatorsValid = () => { const fieldSchema = useFieldSchema(); const operatorList = useOperatorList(); - const { operators: storedOperators } = findFilterOperators(fieldSchema); + const { getOperators, collectOperator } = useOperators(); + const storedOperators = getOperators(); if (storedOperators && operatorList.length && !storedOperators[fieldSchema.name]) { - storedOperators[fieldSchema.name] = operatorList[0].value; + collectOperator(fieldSchema.name, operatorList[0].value); } }; @@ -510,61 +489,51 @@ export const EditOperator = () => { const { t } = useTranslation(); const { dn } = useDesignable(); const operatorList = useOperatorList(); - const { operators: storedOperators = {}, uid } = findFilterOperators(fieldSchema); + const { getOperator, collectOperator } = useOperators(); - if (operatorList.length && !storedOperators[fieldSchema.name]) { - storedOperators[fieldSchema.name] = operatorList[0].value; + if (operatorList.length && !getOperator(fieldSchema.name)) { + collectOperator(fieldSchema.name, operatorList[0].value); } return operatorList.length ? ( { - storedOperators[fieldSchema.name] = v; + collectOperator(fieldSchema.name as string, v); + _.set(fieldSchema, 'x-filter-operator', v); + const operator = operatorList.find((item) => item.value === v); - const schema: ISchema = { - ['x-uid']: uid, - ['x-filter-operators']: storedOperators, - }; let componentProps = {}; // 根据操作符的配置,设置组件的属性 if (operator?.schema?.['x-component']) { - _.set(fieldSchema, 'x-component-props.component', operator.schema['x-component']); - _.set(field, 'componentProps.component', operator.schema['x-component']); + _.set(fieldSchema, 'x-component-props.component', operator.schema?.['x-component']); + _.set(field, 'componentProps.component', operator.schema?.['x-component']); field.reset(); componentProps = { component: operator.schema['x-component'], - ...operator.schema['x-component-props'], + ...operator.schema?.['x-component-props'], }; - dn.emit('patch', { - schema: { - ['x-uid']: fieldSchema['x-uid'], - ['x-component-props']: componentProps, - }, - }); } else if (fieldSchema['x-component-props']?.component) { _.set(fieldSchema, 'x-component-props.component', null); _.set(field, 'componentProps.component', null); field.reset(); componentProps = { component: null, - ...operator.schema['x-component-props'], + ...operator.schema?.['x-component-props'], }; - dn.emit('patch', { - schema: { - ['x-uid']: fieldSchema['x-uid'], - ['x-component-props']: componentProps, - }, - }); } field.componentProps = componentProps; dn.emit('patch', { - schema, + schema: { + ['x-uid']: fieldSchema['x-uid'], + ['x-component-props']: componentProps, + ['x-filter-operator']: v, + }, }); dn.refresh(); }} diff --git a/packages/core/client/src/schema-component/antd/form-v2/Form.Settings.tsx b/packages/core/client/src/schema-component/antd/form-v2/Form.Settings.tsx index de1feb931d378..1ed14c659f164 100644 --- a/packages/core/client/src/schema-component/antd/form-v2/Form.Settings.tsx +++ b/packages/core/client/src/schema-component/antd/form-v2/Form.Settings.tsx @@ -15,17 +15,17 @@ import { useFormBlockContext } from '../../../block-provider'; import { useDetailsBlockContext } from '../../../block-provider/DetailsBlockProvider'; import { useCollection_deprecated } from '../../../collection-manager'; import { useSortFields } from '../../../collection-manager/action-hooks'; +import { setDataLoadingModeSettingsItem } from '../../../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem'; import { - SchemaSettingsBlockTitleItem, SchemaSettingsDataTemplates, SchemaSettingsFormItemTemplate, SchemaSettingsLinkageRules, - SchemaSettingsTemplate, } from '../../../schema-settings/SchemaSettings'; +import { SchemaSettingsBlockTitleItem } from '../../../schema-settings/SchemaSettingsBlockTitleItem'; import { SchemaSettingsDataScope } from '../../../schema-settings/SchemaSettingsDataScope'; +import { SchemaSettingsTemplate } from '../../../schema-settings/SchemaSettingsTemplate'; import { useDesignable } from '../../hooks'; import { removeNullCondition } from '../filter'; -import { setDataLoadingModeSettingsItem } from '../../../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem'; /** * @deprecated diff --git a/packages/core/client/src/schema-component/antd/form-v2/Form.tsx b/packages/core/client/src/schema-component/antd/form-v2/Form.tsx index ba19d2823e151..4c0052edf69bf 100644 --- a/packages/core/client/src/schema-component/antd/form-v2/Form.tsx +++ b/packages/core/client/src/schema-component/antd/form-v2/Form.tsx @@ -18,8 +18,8 @@ import { ConfigProvider, Spin } from 'antd'; import React, { useEffect, useMemo } from 'react'; import { useActionContext } from '..'; import { useAttach, useComponent } from '../..'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; import { useTemplateBlockContext } from '../../../block-provider/TemplateBlockProvider'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { ActionType } from '../../../schema-settings/LinkageRules/type'; import { useToken } from '../../../style'; import { useLocalVariables, useVariables } from '../../../variables'; diff --git a/packages/core/client/src/schema-component/antd/form/Form.Settings.tsx b/packages/core/client/src/schema-component/antd/form/Form.Settings.tsx index e5b07813f199d..6ac7cfedfd4db 100644 --- a/packages/core/client/src/schema-component/antd/form/Form.Settings.tsx +++ b/packages/core/client/src/schema-component/antd/form/Form.Settings.tsx @@ -9,7 +9,7 @@ import { SchemaSettings } from '../../../application/schema-settings'; import { useCollection_deprecated } from '../../../collection-manager'; -import { SchemaSettingsTemplate } from '../../../schema-settings/SchemaSettings'; +import { SchemaSettingsTemplate } from '../../../schema-settings/SchemaSettingsTemplate'; /** * @deprecated diff --git a/packages/core/client/src/schema-component/antd/form/Form.tsx b/packages/core/client/src/schema-component/antd/form/Form.tsx index d081243ddd4bf..f3d339f402b5c 100644 --- a/packages/core/client/src/schema-component/antd/form/Form.tsx +++ b/packages/core/client/src/schema-component/antd/form/Form.tsx @@ -16,12 +16,8 @@ import React, { createContext, useContext, useEffect, useMemo } from 'react'; import { useAttach, useComponent } from '../..'; import { useRequest } from '../../../api-client'; import { useCollection_deprecated } from '../../../collection-manager'; -import { - GeneralSchemaDesigner, - SchemaSettingsDivider, - SchemaSettingsRemove, - SchemaSettingsTemplate, -} from '../../../schema-settings'; +import { GeneralSchemaDesigner, SchemaSettingsDivider, SchemaSettingsRemove } from '../../../schema-settings'; +import { SchemaSettingsTemplate } from '../../../schema-settings/SchemaSettingsTemplate'; import { useSchemaTemplate } from '../../../schema-templates'; type Opts = Options & { uid?: string }; diff --git a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Decorator.tsx b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Decorator.tsx index 5492fe091cd44..94474550e25fb 100644 --- a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Decorator.tsx +++ b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Decorator.tsx @@ -12,9 +12,9 @@ import { createForm } from '@formily/core'; import { FormContext, useField, useFieldSchema } from '@formily/react'; import React, { createContext, useContext, useEffect, useMemo } from 'react'; import { BlockProvider, useBlockRequestContext } from '../../../block-provider/BlockProvider'; -import useStyles from './GridCard.Decorator.style'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { useGridCardBlockParams } from '../../../modules/blocks/data-blocks/grid-card/hooks/useGridCardBlockParams'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; +import useStyles from './GridCard.Decorator.style'; export const GridCardBlockContext = createContext({}); GridCardBlockContext.displayName = 'GridCardBlockContext'; diff --git a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Designer.tsx b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Designer.tsx index 51bc4b815ed34..36effa6928bdc 100644 --- a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Designer.tsx +++ b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Designer.tsx @@ -24,9 +24,9 @@ import { SchemaSettingsModalItem, SchemaSettingsRemove, SchemaSettingsSelectItem, - SchemaSettingsTemplate, } from '../../../schema-settings'; import { SchemaSettingsDataScope } from '../../../schema-settings/SchemaSettingsDataScope'; +import { SchemaSettingsTemplate } from '../../../schema-settings/SchemaSettingsTemplate'; import { useSchemaTemplate } from '../../../schema-templates'; import { SchemaComponentOptions } from '../../core'; import { useDesignable } from '../../hooks'; diff --git a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx index 856da986c96b7..b64f9a76cb66d 100644 --- a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx +++ b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx @@ -12,8 +12,8 @@ import { ObjectField } from '@formily/core'; import { useField } from '@formily/react'; import { Card } from 'antd'; import React from 'react'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; import { useCollectionParentRecordData } from '../../../data-source/collection-record/CollectionRecordProvider'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { RecordProvider } from '../../../record-provider'; const itemCss = css` diff --git a/packages/core/client/src/schema-component/antd/grid-card/GridCard.tsx b/packages/core/client/src/schema-component/antd/grid-card/GridCard.tsx index c86e6b040bfb4..0ddd24278bec1 100644 --- a/packages/core/client/src/schema-component/antd/grid-card/GridCard.tsx +++ b/packages/core/client/src/schema-component/antd/grid-card/GridCard.tsx @@ -12,6 +12,7 @@ import { ArrayField } from '@formily/core'; import { RecursionField, Schema, useField, useFieldSchema } from '@formily/react'; import { List as AntdList, Col, PaginationProps } from 'antd'; import React, { useCallback, useState } from 'react'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { SortableItem } from '../../common'; import { SchemaComponentOptions } from '../../core'; import { useDesigner, useProps } from '../../hooks'; @@ -20,7 +21,6 @@ import { GridCardDesigner } from './GridCard.Designer'; import { GridCardItem } from './GridCard.Item'; import { useGridCardActionBarProps } from './hooks'; import { defaultColumnCount, pageSizeOptions } from './options'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; const rowGutter = { md: 12, diff --git a/packages/core/client/src/schema-component/antd/list/List.Decorator.tsx b/packages/core/client/src/schema-component/antd/list/List.Decorator.tsx index 425d6b6754fb5..0bd556350fd66 100644 --- a/packages/core/client/src/schema-component/antd/list/List.Decorator.tsx +++ b/packages/core/client/src/schema-component/antd/list/List.Decorator.tsx @@ -14,8 +14,8 @@ import { FormContext, useField } from '@formily/react'; import _ from 'lodash'; import React, { createContext, useContext, useEffect, useMemo } from 'react'; import { BlockProvider, useBlockRequestContext } from '../../../block-provider/BlockProvider'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; import { useParsedFilter } from '../../../block-provider/hooks/useParsedFilter'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; export const ListBlockContext = createContext({}); ListBlockContext.displayName = 'ListBlockContext'; diff --git a/packages/core/client/src/schema-component/antd/list/List.Designer.tsx b/packages/core/client/src/schema-component/antd/list/List.Designer.tsx index e5bf7b4108441..22d9aed535383 100644 --- a/packages/core/client/src/schema-component/antd/list/List.Designer.tsx +++ b/packages/core/client/src/schema-component/antd/list/List.Designer.tsx @@ -14,21 +14,21 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { useFormBlockContext } from '../../../block-provider'; import { useCollection_deprecated, useSortFields } from '../../../collection-manager'; +import { SetDataLoadingMode } from '../../../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem'; import { useRecord } from '../../../record-provider'; import { GeneralSchemaDesigner, - SchemaSettingsBlockTitleItem, SchemaSettingsDivider, SchemaSettingsModalItem, SchemaSettingsRemove, SchemaSettingsSelectItem, - SchemaSettingsTemplate, } from '../../../schema-settings'; +import { SchemaSettingsBlockTitleItem } from '../../../schema-settings/SchemaSettingsBlockTitleItem'; +import { SchemaSettingsDataScope } from '../../../schema-settings/SchemaSettingsDataScope'; +import { SchemaSettingsTemplate } from '../../../schema-settings/SchemaSettingsTemplate'; import { useSchemaTemplate } from '../../../schema-templates'; import { useDesignable } from '../../hooks'; import { removeNullCondition } from '../filter'; -import { SchemaSettingsDataScope } from '../../../schema-settings/SchemaSettingsDataScope'; -import { SetDataLoadingMode } from '../../../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem'; /** * @deprecated - 已使用 SchemaSettings 替代 diff --git a/packages/core/client/src/schema-component/antd/list/List.Item.tsx b/packages/core/client/src/schema-component/antd/list/List.Item.tsx index 24694b1be3f72..853feeeb2d8d4 100644 --- a/packages/core/client/src/schema-component/antd/list/List.Item.tsx +++ b/packages/core/client/src/schema-component/antd/list/List.Item.tsx @@ -14,8 +14,8 @@ import classnames from 'classnames'; import React from 'react'; import { useDesignable } from '../../hooks'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; import { useCollectionParentRecordData } from '../../../data-source/collection-record/CollectionRecordProvider'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { RecordProvider } from '../../../record-provider'; export const ListItem = withDynamicSchemaProps((props) => { diff --git a/packages/core/client/src/schema-component/antd/list/List.tsx b/packages/core/client/src/schema-component/antd/list/List.tsx index 721832bd62a13..273cadab577a2 100644 --- a/packages/core/client/src/schema-component/antd/list/List.tsx +++ b/packages/core/client/src/schema-component/antd/list/List.tsx @@ -12,6 +12,7 @@ import { ArrayField } from '@formily/core'; import { RecursionField, Schema, useField, useFieldSchema } from '@formily/react'; import { List as AntdList, PaginationProps } from 'antd'; import React, { useCallback, useState } from 'react'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { SortableItem } from '../../common'; import { SchemaComponentOptions } from '../../core'; import { useDesigner } from '../../hooks'; @@ -20,7 +21,6 @@ import { ListDesigner } from './List.Designer'; import { ListItem } from './List.Item'; import useStyles from './List.style'; import { useListActionBarProps } from './hooks'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; const InternalList = (props) => { const { service } = useListBlockContext(); diff --git a/packages/core/client/src/schema-component/antd/page/FixedBlock.tsx b/packages/core/client/src/schema-component/antd/page/FixedBlock.tsx index e47589aa06b06..d52446b16760f 100644 --- a/packages/core/client/src/schema-component/antd/page/FixedBlock.tsx +++ b/packages/core/client/src/schema-component/antd/page/FixedBlock.tsx @@ -10,7 +10,6 @@ import { css } from '@emotion/css'; import { useField, useFieldSchema } from '@formily/react'; import React, { useContext, useEffect, useRef, useState } from 'react'; -import { useRecord } from '../../../record-provider'; const FixedBlockContext = React.createContext<{ setFixedBlock: (value: string | false) => void; diff --git a/packages/core/client/src/schema-component/antd/page/PageTabDesigner.tsx b/packages/core/client/src/schema-component/antd/page/PageTabDesigner.tsx index a4c29f8d43181..78d8a11b812d5 100644 --- a/packages/core/client/src/schema-component/antd/page/PageTabDesigner.tsx +++ b/packages/core/client/src/schema-component/antd/page/PageTabDesigner.tsx @@ -12,7 +12,7 @@ import { useFieldSchema } from '@formily/react'; import { Space } from 'antd'; import React from 'react'; import { DragHandler, useDesignable } from '../..'; -import { useSchemaSettingsRender } from '../../../application/schema-settings/hooks'; +import { useSchemaSettingsRender } from '../../../application/schema-settings/hooks/useSchemaSettingsRender'; import { SchemaToolbarProvider } from '../../../application/schema-toolbar/context'; import { useGetAriaLabelOfDesigner } from '../../../schema-settings/hooks/useGetAriaLabelOfDesigner'; diff --git a/packages/core/client/src/schema-component/antd/pagination/index.tsx b/packages/core/client/src/schema-component/antd/pagination/index.tsx index 5c520439c5b0d..dab98b1a51f5c 100644 --- a/packages/core/client/src/schema-component/antd/pagination/index.tsx +++ b/packages/core/client/src/schema-component/antd/pagination/index.tsx @@ -10,8 +10,8 @@ import { observer } from '@formily/react'; import { Pagination as AntdPagination, PaginationProps as AntdPaginationProps } from 'antd'; import React, { KeyboardEventHandler } from 'react'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { useProps } from '../../hooks/useProps'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; export interface PaginationProps extends AntdPaginationProps { hidden?: boolean; diff --git a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx index 43f0b551be348..c34e0771bcee1 100644 --- a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx +++ b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx @@ -35,8 +35,8 @@ import { useTableSelectorContext, } from '../../../'; import { useACLFieldWhitelist } from '../../../acl/ACLProvider'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; import { isNewRecord } from '../../../data-source/collection-record/isNewRecord'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { useToken } from '../__builtins__'; import { SubFormProvider } from '../association-field/hooks'; import { ColumnFieldProvider } from './components/ColumnFieldProvider'; diff --git a/packages/core/client/src/schema-component/antd/table-v2/TableBlockDesigner.tsx b/packages/core/client/src/schema-component/antd/table-v2/TableBlockDesigner.tsx index 8a7b568873518..0e0e72ae8b2cd 100644 --- a/packages/core/client/src/schema-component/antd/table-v2/TableBlockDesigner.tsx +++ b/packages/core/client/src/schema-component/antd/table-v2/TableBlockDesigner.tsx @@ -8,34 +8,33 @@ */ import { ArrayItems } from '@formily/antd-v5'; -import { ISchema, useField, useFieldSchema } from '@formily/react'; import { Field } from '@formily/core'; +import { ISchema, useField, useFieldSchema } from '@formily/react'; import React, { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; +import { useCompile } from '../../'; import { useAPIClient } from '../../../api-client'; import { useFormBlockContext, useTableBlockContext } from '../../../block-provider'; import { useCollectionManager_deprecated, useCollection_deprecated } from '../../../collection-manager'; import { useSortFields } from '../../../collection-manager/action-hooks'; import { FilterBlockType, mergeFilter } from '../../../filter-provider/utils'; -import { useRecord } from '../../../record-provider'; +import { SetDataLoadingMode } from '../../../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem'; import { GeneralSchemaDesigner, - SchemaSettingsBlockTitleItem, - SchemaSettingsConnectDataBlocks, SchemaSettingsDivider, SchemaSettingsModalItem, SchemaSettingsRemove, SchemaSettingsSelectItem, SchemaSettingsSwitchItem, - SchemaSettingsTemplate, } from '../../../schema-settings'; +import { SchemaSettingsBlockTitleItem } from '../../../schema-settings/SchemaSettingsBlockTitleItem'; +import { SchemaSettingsConnectDataBlocks } from '../../../schema-settings/SchemaSettingsConnectDataBlocks'; +import { SchemaSettingsDataScope } from '../../../schema-settings/SchemaSettingsDataScope'; +import { SchemaSettingsTemplate } from '../../../schema-settings/SchemaSettingsTemplate'; import { useSchemaTemplate } from '../../../schema-templates'; import { useDesignable } from '../../hooks'; import { removeNullCondition } from '../filter'; -import { useCompile } from '../../'; -import { SchemaSettingsDataScope } from '../../../schema-settings/SchemaSettingsDataScope'; import { FixedBlockDesignerItem } from '../page/FixedBlockDesignerItem'; -import { SetDataLoadingMode } from '../../../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem'; export const EditSortField = () => { const { fields } = useCollection_deprecated(); diff --git a/packages/core/client/src/schema-component/antd/table-v2/__tests__/Table.settings.test.tsx b/packages/core/client/src/schema-component/antd/table-v2/__tests__/Table.settings.test.tsx index ac32d8b0c79a3..fbf8aa62cfc1e 100644 --- a/packages/core/client/src/schema-component/antd/table-v2/__tests__/Table.settings.test.tsx +++ b/packages/core/client/src/schema-component/antd/table-v2/__tests__/Table.settings.test.tsx @@ -14,13 +14,13 @@ import { useTableBlockDecoratorProps, } from '@nocobase/client'; import { + CheckSettingsOptions, + checkSchema, checkSettings, renderSettings, - checkSchema, screen, userEvent, waitFor, - CheckSettingsOptions, } from '@nocobase/test/client'; import { withSchema } from '@nocobase/test/web'; diff --git a/packages/core/client/src/schema-component/antd/table/Table.Void.Designer.tsx b/packages/core/client/src/schema-component/antd/table/Table.Void.Designer.tsx index 19d0d2932347e..61d4ab8d401bf 100644 --- a/packages/core/client/src/schema-component/antd/table/Table.Void.Designer.tsx +++ b/packages/core/client/src/schema-component/antd/table/Table.Void.Designer.tsx @@ -20,8 +20,8 @@ import { SchemaSettingsRemove, SchemaSettingsSelectItem, SchemaSettingsSwitchItem, - SchemaSettingsTemplate, } from '../../../schema-settings'; +import { SchemaSettingsTemplate } from '../../../schema-settings/SchemaSettingsTemplate'; import { useSchemaTemplate } from '../../../schema-templates'; import { useDesignable } from '../../hooks'; diff --git a/packages/core/client/src/schema-component/antd/upload/Upload.tsx b/packages/core/client/src/schema-component/antd/upload/Upload.tsx index 8e22fdfd7e2d7..2224989bed289 100644 --- a/packages/core/client/src/schema-component/antd/upload/Upload.tsx +++ b/packages/core/client/src/schema-component/antd/upload/Upload.tsx @@ -16,7 +16,7 @@ import React, { useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import LightBox from 'react-image-lightbox'; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; import { useProps } from '../../hooks/useProps'; import { ReadPretty } from './ReadPretty'; import { isImage, isPdf, toArr, toFileList, toItem, toValue, useUploadProps } from './shared'; diff --git a/packages/core/client/src/schema-initializer/utils.ts b/packages/core/client/src/schema-initializer/utils.ts index 756a1483a45f1..e4f56a0fabf2a 100644 --- a/packages/core/client/src/schema-initializer/utils.ts +++ b/packages/core/client/src/schema-initializer/utils.ts @@ -382,6 +382,7 @@ export const useFilterFormItemInitializerFields = (options?: any) => { 'x-settings': 'fieldSettings:FilterFormItem', 'x-component': 'CollectionField', 'x-decorator': 'FormItem', + 'x-use-decorator-props': 'useFormItemProps', 'x-collection-field': `${name}.${field.name}`, 'x-component-props': {}, }; @@ -395,6 +396,7 @@ export const useFilterFormItemInitializerFields = (options?: any) => { 'x-settings': 'fieldSettings:FilterFormItem', 'x-component': 'CollectionField', 'x-decorator': 'FormItem', + 'x-use-decorator-props': 'useFormItemProps', 'x-collection-field': `${name}.${field.name}`, 'x-component-props': field.uiSchema?.['x-component-props'], }; diff --git a/packages/core/client/src/schema-settings/DataTemplates/FormDataTemplates.tsx b/packages/core/client/src/schema-settings/DataTemplates/FormDataTemplates.tsx index 5f4ea8ee964fd..cade0cd743595 100644 --- a/packages/core/client/src/schema-settings/DataTemplates/FormDataTemplates.tsx +++ b/packages/core/client/src/schema-settings/DataTemplates/FormDataTemplates.tsx @@ -16,6 +16,7 @@ import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useCollectionManager_deprecated } from '../../collection-manager'; import { mergeFilter } from '../../filter-provider/utils'; +import { withDynamicSchemaProps } from '../../hoc/withDynamicSchemaProps'; import { SchemaComponent, SchemaComponentContext, removeNullCondition, useProps } from '../../schema-component'; import { ITemplate } from '../../schema-component/antd/form-v2/Templates'; import { VariableInput } from '../VariableInput'; @@ -24,7 +25,6 @@ import { ArrayCollapse } from './components/DataTemplateTitle'; import { getSelectedIdFilter } from './components/Designer'; import { useCollectionState } from './hooks/useCollectionState'; import { useSyncFromForm } from './utils'; -import { withDynamicSchemaProps } from '../../application/hoc/withDynamicSchemaProps'; const Tree = connect( AntdTree, diff --git a/packages/core/client/src/schema-settings/EnableChildCollections/index.tsx b/packages/core/client/src/schema-settings/EnableChildCollections/index.tsx index a4d9c315ee5e5..792097230dfd9 100644 --- a/packages/core/client/src/schema-settings/EnableChildCollections/index.tsx +++ b/packages/core/client/src/schema-settings/EnableChildCollections/index.tsx @@ -11,8 +11,8 @@ import { observer, useForm } from '@formily/react'; import { action } from '@formily/reactive'; import React from 'react'; import { useCollectionManager_deprecated } from '../../collection-manager'; +import { withDynamicSchemaProps } from '../../hoc/withDynamicSchemaProps'; import { SchemaComponent, useCompile, useProps } from '../../schema-component'; -import { withDynamicSchemaProps } from '../../application/hoc/withDynamicSchemaProps'; export const EnableChildCollections = withDynamicSchemaProps( observer((props: any) => { diff --git a/packages/core/client/src/schema-settings/GeneralSchemaDesigner.tsx b/packages/core/client/src/schema-settings/GeneralSchemaDesigner.tsx index c87e5a5e7ba29..a4b6aeea3db01 100644 --- a/packages/core/client/src/schema-settings/GeneralSchemaDesigner.tsx +++ b/packages/core/client/src/schema-settings/GeneralSchemaDesigner.tsx @@ -14,13 +14,8 @@ import { Space } from 'antd'; import classNames from 'classnames'; import React, { FC, useEffect, useMemo, useRef } from 'react'; import { useTranslation } from 'react-i18next'; -import { - SchemaInitializer, - SchemaSettings, - SchemaToolbarProvider, - useSchemaInitializerRender, - useSchemaSettingsRender, -} from '../application'; +import { SchemaInitializer, SchemaSettings, SchemaToolbarProvider, useSchemaInitializerRender } from '../application'; +import { useSchemaSettingsRender } from '../application/schema-settings/hooks/useSchemaSettingsRender'; import { useDataSourceManager } from '../data-source/data-source/DataSourceManagerProvider'; import { useDataSource } from '../data-source/data-source/DataSourceProvider'; import { DragHandler, useCompile, useDesignable, useGridContext, useGridRowContext } from '../schema-component'; diff --git a/packages/core/client/src/schema-settings/LinkageRules/LinkageRuleActionGroup.tsx b/packages/core/client/src/schema-settings/LinkageRules/LinkageRuleActionGroup.tsx index f427299e6ca98..2c7cf02931508 100644 --- a/packages/core/client/src/schema-settings/LinkageRules/LinkageRuleActionGroup.tsx +++ b/packages/core/client/src/schema-settings/LinkageRules/LinkageRuleActionGroup.tsx @@ -12,10 +12,10 @@ import { ArrayField, ObjectField, observer, useField } from '@formily/react'; import { Space } from 'antd'; import React, { useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; +import { withDynamicSchemaProps } from '../../hoc/withDynamicSchemaProps'; +import { useProps } from '../../schema-component/hooks/useProps'; import { FormButtonLinkageRuleAction, FormFieldLinkageRuleAction } from './LinkageRuleAction'; import { RemoveActionContext } from './context'; -import { withDynamicSchemaProps } from '../../application/hoc/withDynamicSchemaProps'; -import { useProps } from '../../schema-component/hooks/useProps'; export const LinkageRuleActions = observer( (props: any): any => { const { type, linkageOptions } = props; diff --git a/packages/core/client/src/schema-settings/LinkageRules/index.tsx b/packages/core/client/src/schema-settings/LinkageRules/index.tsx index 3f06124b5af92..cd538e530beb9 100644 --- a/packages/core/client/src/schema-settings/LinkageRules/index.tsx +++ b/packages/core/client/src/schema-settings/LinkageRules/index.tsx @@ -10,10 +10,10 @@ import { css } from '@emotion/css'; import { observer, useFieldSchema } from '@formily/react'; import React, { useMemo } from 'react'; -import { withDynamicSchemaProps } from '../../application/hoc/withDynamicSchemaProps'; import { FormBlockContext } from '../../block-provider'; import { useCollectionManager_deprecated } from '../../collection-manager'; import { useCollectionParentRecordData } from '../../data-source/collection-record/CollectionRecordProvider'; +import { withDynamicSchemaProps } from '../../hoc/withDynamicSchemaProps'; import { RecordProvider } from '../../record-provider'; import { SchemaComponent, useProps } from '../../schema-component'; import { DynamicComponentProps } from '../../schema-component/antd/filter/DynamicComponent'; diff --git a/packages/core/client/src/schema-settings/SchemaSettings.tsx b/packages/core/client/src/schema-settings/SchemaSettings.tsx index 76f815750c8af..16296446bc2d0 100644 --- a/packages/core/client/src/schema-settings/SchemaSettings.tsx +++ b/packages/core/client/src/schema-settings/SchemaSettings.tsx @@ -12,7 +12,6 @@ import { ArrayCollapse, ArrayItems, FormItem, FormLayout, Input } from '@formily import { Field, GeneralField, createForm } from '@formily/core'; import { ISchema, Schema, SchemaOptionsContext, useField, useFieldSchema, useForm } from '@formily/react'; import { uid } from '@formily/shared'; -import { error } from '@nocobase/utils/client'; import type { DropdownProps } from 'antd'; import { Alert, @@ -22,7 +21,6 @@ import { CascaderProps, ConfigProvider, Dropdown, - Empty, MenuItemProps, MenuProps, Modal, @@ -46,65 +44,47 @@ import React, { import { createPortal } from 'react-dom'; import { useTranslation } from 'react-i18next'; import { Router } from 'react-router-dom'; +import { APIClientProvider } from '../api-client/APIClientProvider'; +import { useAPIClient } from '../api-client/hooks/useAPIClient'; +import { FormBlockContext, findFormBlock, useFormBlockContext, useFormBlockType } from '../block-provider'; import { - APIClientProvider, - ActionContextProvider, - AssociationOrCollectionProvider, - CollectionFieldOptions_deprecated, - CollectionRecordProvider, - DataSourceApplicationProvider, - Designable, - FormDialog, - FormProvider, - RemoteSchemaComponent, - SchemaComponent, - SchemaComponentContext, - SchemaComponentOptions, - createDesignable, - findFormBlock, - useAPIClient, - useCollectionManager_deprecated, - useCollectionRecord, - useCollection_deprecated, - useCompile, - useDataBlockProps, - useDesignable, - useGlobalTheme, - useLinkageCollectionFilterOptions, - useRecord, - useSortFields, -} from '..'; -import { FormBlockContext, useFormBlockContext, useFormBlockType, useTableBlockContext } from '../block-provider'; -import { - FormActiveFieldsProvider, - findFilterTargets, - updateFilterTargets, - useFormActiveFields, -} from '../block-provider/hooks'; -import { - useBlockRequestContext, + BlockContext, BlockRequestContext_deprecated, useBlockContext, - BlockContext, + useBlockRequestContext, } from '../block-provider/BlockProvider'; +import { FormActiveFieldsProvider, useFormActiveFields } from '../block-provider/hooks'; +import { useLinkageCollectionFilterOptions, useSortFields } from '../collection-manager/action-hooks'; +import { useCollectionManager_deprecated } from '../collection-manager/hooks/useCollectionManager_deprecated'; +import { useCollection_deprecated } from '../collection-manager/hooks/useCollection_deprecated'; +import { CollectionFieldOptions_deprecated } from '../collection-manager/types'; import { SelectWithTitle, SelectWithTitleProps } from '../common/SelectWithTitle'; import { useNiceDropdownMaxHeight } from '../common/useNiceDropdownHeight'; +import { + CollectionRecordProvider, + useCollectionRecord, +} from '../data-source/collection-record/CollectionRecordProvider'; +import { DataSourceApplicationProvider } from '../data-source/components/DataSourceApplicationProvider'; +import { AssociationOrCollectionProvider, useDataBlockProps } from '../data-source/data-block/DataBlockProvider'; import { useDataSourceManager } from '../data-source/data-source/DataSourceManagerProvider'; import { useDataSourceKey } from '../data-source/data-source/DataSourceProvider'; -import { - FilterBlockType, - getSupportFieldsByAssociation, - getSupportFieldsByForeignKey, - isSameCollection, - useSupportedBlocks, -} from '../filter-provider/utils'; import { useFilterBlock } from '../filter-provider/FilterProvider'; import { FlagProvider } from '../flag-provider'; +import { useGlobalTheme } from '../global-theme'; import { useCollectMenuItem, useCollectMenuItems, useMenuItem } from '../hooks/useMenuItem'; import { DeclareVariable } from '../modules/variable/DeclareVariable'; import { useVariable } from '../modules/variable/useVariable'; +import { useRecord } from '../record-provider'; +import { ActionContextProvider } from '../schema-component/antd/action/context'; import { SubFormProvider, useSubFormValue } from '../schema-component/antd/association-field/hooks'; -import { getTargetKey } from '../schema-component/antd/association-filter/utilts'; +import { FormDialog } from '../schema-component/antd/form-dialog'; +import { SchemaComponentContext } from '../schema-component/context'; +import { FormProvider } from '../schema-component/core/FormProvider'; +import { RemoteSchemaComponent } from '../schema-component/core/RemoteSchemaComponent'; +import { SchemaComponent } from '../schema-component/core/SchemaComponent'; +import { SchemaComponentOptions } from '../schema-component/core/SchemaComponentOptions'; +import { useCompile } from '../schema-component/hooks/useCompile'; +import { Designable, createDesignable, useDesignable } from '../schema-component/hooks/useDesignable'; import { useSchemaTemplateManager } from '../schema-templates'; import { useBlockTemplateContext } from '../schema-templates/BlockTemplate'; import { useLocalVariables, useVariables } from '../variables'; @@ -207,103 +187,6 @@ export const SchemaSettingsDropdown: React.FC = (props) => ); }; -export const SchemaSettingsTemplate = function Template(props) { - const { componentName, collectionName, resourceName, needRender } = props; - const { t } = useTranslation(); - const { getCollection } = useCollectionManager_deprecated(); - const { dn, setVisible, template, fieldSchema } = useSchemaSettings(); - const compile = useCompile(); - const api = useAPIClient(); - const { dn: tdn } = useBlockTemplateContext(); - const { saveAsTemplate, copyTemplateSchema } = useSchemaTemplateManager(); - const { theme } = useGlobalTheme(); - - if (!collectionName && !needRender) { - return null; - } - if (template) { - return ( - { - const schema = await copyTemplateSchema(template); - const removed = tdn.removeWithoutEmit(); - tdn.insertAfterEnd(schema, { - async onSuccess() { - await api.request({ - url: `/uiSchemas:remove/${removed['x-uid']}`, - }); - }, - }); - }} - > - {t('Convert reference to duplicate')} - - ); - } - return ( - { - setVisible(false); - const collection = collectionName && getCollection(collectionName); - const values = await FormDialog( - t('Save as template'), - () => { - return ( - - - - ); - }, - theme, - ).open({}); - const sdn = createDesignable({ - t, - api, - refresh: dn.refresh.bind(dn), - current: fieldSchema.parent, - }); - sdn.loadAPIClientEvents(); - const { key } = await saveAsTemplate({ - collectionName, - resourceName, - componentName, - dataSourceKey: collection.dataSource, - name: values.name, - uid: fieldSchema['x-uid'], - }); - sdn.removeWithoutEmit(fieldSchema); - sdn.insertBeforeEnd({ - type: 'void', - 'x-component': 'BlockTemplate', - 'x-component-props': { - templateId: key, - }, - }); - }} - > - {t('Save as template')} - - ); -}; - const findGridSchema = (fieldSchema) => { return fieldSchema.reduceProperties((buf, s) => { if (s['x-component'] === 'FormV2' || s['x-component'] === 'Details') { @@ -609,144 +492,6 @@ export const SchemaSettingsRemove: FC = (props) => { ); }; -interface SchemaSettingsConnectDataBlocksProps { - type: FilterBlockType; - emptyDescription?: string; -} - -export const SchemaSettingsConnectDataBlocks: FC = (props) => { - const { type, emptyDescription } = props; - const fieldSchema = useFieldSchema(); - const { dn } = useDesignable(); - const { t } = useTranslation(); - const collection = useCollection_deprecated(); - const { inProvider } = useFilterBlock(); - const dataBlocks = useSupportedBlocks(type); - // eslint-disable-next-line prefer-const - let { targets = [], uid } = findFilterTargets(fieldSchema); - const compile = useCompile(); - const { getAllCollectionsInheritChain } = useCollectionManager_deprecated(); - - if (!inProvider) { - return null; - } - - const Content = dataBlocks.map((block) => { - const title = `${compile(block.collection.title)} #${block.uid.slice(0, 4)}`; - const onHover = () => { - const dom = block.dom; - const designer = dom.querySelector('.general-schema-designer') as HTMLElement; - if (designer) { - designer.style.display = 'block'; - } - dom.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.2)'; - dom.scrollIntoView({ - behavior: 'smooth', - block: 'center', - }); - }; - const onLeave = () => { - const dom = block.dom; - const designer = dom.querySelector('.general-schema-designer') as HTMLElement; - if (designer) { - designer.style.display = null; - } - dom.style.boxShadow = 'none'; - }; - if (isSameCollection(block.collection, collection)) { - return ( - target.uid === block.uid)} - onChange={(checked) => { - if (checked) { - targets.push({ uid: block.uid }); - } else { - targets = targets.filter((target) => target.uid !== block.uid); - block.clearFilter(uid); - } - - updateFilterTargets(fieldSchema, targets); - dn.emit('patch', { - schema: { - ['x-uid']: uid, - 'x-filter-targets': targets, - }, - }).catch(error); - dn.refresh(); - }} - onMouseEnter={onHover} - onMouseLeave={onLeave} - /> - ); - } - - const target = targets.find((target) => target.uid === block.uid); - // 与筛选区块的数据表具有关系的表 - return ( - { - return { - label: compile(field.uiSchema.title) || field.name, - value: `${field.name}.${getTargetKey(field)}`, - }; - }), - ...getSupportFieldsByForeignKey(collection, block).map((field) => { - return { - label: `${compile(field.uiSchema.title) || field.name} [${t('Foreign key')}]`, - value: field.name, - }; - }), - { - label: t('Unconnected'), - value: '', - }, - ]} - onChange={(value) => { - if (value === '') { - targets = targets.filter((target) => target.uid !== block.uid); - block.clearFilter(uid); - } else { - targets = targets.filter((target) => target.uid !== block.uid); - targets.push({ uid: block.uid, field: value }); - } - updateFilterTargets(fieldSchema, targets); - dn.emit('patch', { - schema: { - ['x-uid']: uid, - 'x-filter-targets': targets, - }, - }); - dn.refresh(); - }} - onMouseEnter={onHover} - onMouseLeave={onLeave} - /> - ); - }); - - return ( - - {Content.length ? ( - Content - ) : ( - - - - )} - - ); -}; - export interface SchemaSettingsSelectItemProps extends Omit, Omit { @@ -1087,47 +832,6 @@ export const SchemaSettingsModalItem: FC = (props) ); }; -export const SchemaSettingsBlockTitleItem = function BlockTitleItem() { - const field = useField(); - const fieldSchema = useFieldSchema(); - const { dn } = useDesignable(); - const { t } = useTranslation(); - - return ( - { - const componentProps = fieldSchema['x-component-props'] || {}; - componentProps.title = title; - fieldSchema['x-component-props'] = componentProps; - field.componentProps.title = title; - dn.emit('patch', { - schema: { - ['x-uid']: fieldSchema['x-uid'], - 'x-component-props': fieldSchema['x-component-props'], - }, - }); - dn.refresh(); - }} - /> - ); -}; - export const SchemaSettingsDefaultSortingRules = function DefaultSortingRules(props) { const { path = 'x-component-props.params.sort' } = props; const { t } = useTranslation(); @@ -1500,48 +1204,6 @@ export const findParentFieldSchema = (fieldSchema: Schema) => { } }; -export const SchemaSettingsSortField = () => { - const { fields } = useCollection_deprecated(); - const field = useField(); - const fieldSchema = useFieldSchema(); - const { t } = useTranslation(); - const { dn } = useDesignable(); - const compile = useCompile(); - const { service, association } = useTableBlockContext(); - const { getCollectionJoinField } = useCollectionManager_deprecated(); - const collectionField = getCollectionJoinField(association); - const options = fields - .filter((field) => !field?.target && field.interface === 'sort') - .map((field) => { - return { - value: field?.name, - label: compile(field?.uiSchema?.title) || field?.name, - disabled: field?.scopeKey && collectionField?.foreignKey !== field.scopeKey, - }; - }); - - return ( - { - fieldSchema['x-decorator-props'].dragSortBy = dragSortBy; - service.run({ ...service.params?.[0], sort: dragSortBy }); - field.decoratorProps.dragSortBy = dragSortBy; - dn.emit('patch', { - schema: { - ['x-uid']: fieldSchema['x-uid'], - 'x-decorator-props': fieldSchema['x-decorator-props'], - }, - }); - dn.refresh(); - }} - /> - ); -}; - // 是否是系统字段 export const isSystemField = (collectionField: CollectionFieldOptions_deprecated, getInterface) => { const i = getInterface?.(collectionField?.interface); diff --git a/packages/core/client/src/schema-settings/SchemaSettingsBlockTitleItem.tsx b/packages/core/client/src/schema-settings/SchemaSettingsBlockTitleItem.tsx new file mode 100644 index 0000000000000..e356366f34fbd --- /dev/null +++ b/packages/core/client/src/schema-settings/SchemaSettingsBlockTitleItem.tsx @@ -0,0 +1,55 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import { ISchema, useField, useFieldSchema } from '@formily/react'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { useDesignable } from '../schema-component/hooks/useDesignable'; +import { SchemaSettingsModalItem } from './SchemaSettings'; + +export function SchemaSettingsBlockTitleItem() { + const field = useField(); + const fieldSchema = useFieldSchema(); + const { dn } = useDesignable(); + const { t } = useTranslation(); + + return ( + { + const componentProps = fieldSchema['x-component-props'] || {}; + componentProps.title = title; + fieldSchema['x-component-props'] = componentProps; + field.componentProps.title = title; + dn.emit('patch', { + schema: { + ['x-uid']: fieldSchema['x-uid'], + 'x-component-props': fieldSchema['x-component-props'], + }, + }); + dn.refresh(); + }} + /> + ); +} diff --git a/packages/core/client/src/schema-settings/SchemaSettingsConnectDataBlocks.tsx b/packages/core/client/src/schema-settings/SchemaSettingsConnectDataBlocks.tsx new file mode 100644 index 0000000000000..5600157c6df55 --- /dev/null +++ b/packages/core/client/src/schema-settings/SchemaSettingsConnectDataBlocks.tsx @@ -0,0 +1,166 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import { useFieldSchema } from '@formily/react'; +import { error } from '@nocobase/utils/client'; +import { Empty } from 'antd'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { findFilterTargets, updateFilterTargets } from '../block-provider/hooks'; +import { useCollectionManager_deprecated } from '../collection-manager/hooks/useCollectionManager_deprecated'; +import { useCollection_deprecated } from '../collection-manager/hooks/useCollection_deprecated'; +import { useFilterBlock } from '../filter-provider/FilterProvider'; +import { + getSupportFieldsByAssociation, + getSupportFieldsByForeignKey, + isSameCollection, + useSupportedBlocks, +} from '../filter-provider/utils'; +import { getTargetKey } from '../schema-component/antd/association-filter/utilts'; +import { useCompile } from '../schema-component/hooks/useCompile'; +import { useDesignable } from '../schema-component/hooks/useDesignable'; +import { + SchemaSettingsItem, + SchemaSettingsSelectItem, + SchemaSettingsSubMenu, + SchemaSettingsSwitchItem, +} from './SchemaSettings'; + +export function SchemaSettingsConnectDataBlocks(props) { + const { type, emptyDescription } = props; + const fieldSchema = useFieldSchema(); + const { dn } = useDesignable(); + const { t } = useTranslation(); + const collection = useCollection_deprecated(); + const { inProvider } = useFilterBlock(); + const dataBlocks = useSupportedBlocks(type); + // eslint-disable-next-line prefer-const + let { targets = [], uid } = findFilterTargets(fieldSchema); + const compile = useCompile(); + const { getAllCollectionsInheritChain } = useCollectionManager_deprecated(); + + if (!inProvider) { + return null; + } + + const Content = dataBlocks.map((block) => { + const title = `${compile(block.collection.title)} #${block.uid.slice(0, 4)}`; + const onHover = () => { + const dom = block.dom; + const designer = dom.querySelector('.general-schema-designer') as HTMLElement; + if (designer) { + designer.style.display = 'block'; + } + dom.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.2)'; + dom.scrollIntoView({ + behavior: 'smooth', + block: 'center', + }); + }; + const onLeave = () => { + const dom = block.dom; + const designer = dom.querySelector('.general-schema-designer') as HTMLElement; + if (designer) { + designer.style.display = null; + } + dom.style.boxShadow = 'none'; + }; + if (isSameCollection(block.collection, collection)) { + return ( + target.uid === block.uid)} + onChange={(checked) => { + if (checked) { + targets.push({ uid: block.uid }); + } else { + targets = targets.filter((target) => target.uid !== block.uid); + block.clearFilter(uid); + } + + updateFilterTargets(fieldSchema, targets); + dn.emit('patch', { + schema: { + ['x-uid']: uid, + 'x-filter-targets': targets, + }, + }).catch(error); + dn.refresh(); + }} + onMouseEnter={onHover} + onMouseLeave={onLeave} + /> + ); + } + + const target = targets.find((target) => target.uid === block.uid); + // 与筛选区块的数据表具有关系的表 + return ( + { + return { + label: compile(field.uiSchema.title) || field.name, + value: `${field.name}.${getTargetKey(field)}`, + }; + }), + ...getSupportFieldsByForeignKey(collection, block).map((field) => { + return { + label: `${compile(field.uiSchema.title) || field.name} [${t('Foreign key')}]`, + value: field.name, + }; + }), + { + label: t('Unconnected'), + value: '', + }, + ]} + onChange={(value) => { + if (value === '') { + targets = targets.filter((target) => target.uid !== block.uid); + block.clearFilter(uid); + } else { + targets = targets.filter((target) => target.uid !== block.uid); + targets.push({ uid: block.uid, field: value }); + } + updateFilterTargets(fieldSchema, targets); + dn.emit('patch', { + schema: { + ['x-uid']: uid, + 'x-filter-targets': targets, + }, + }); + dn.refresh(); + }} + onMouseEnter={onHover} + onMouseLeave={onLeave} + /> + ); + }); + + return ( + + {Content.length ? ( + Content + ) : ( + + + + )} + + ); +} diff --git a/packages/core/client/src/schema-settings/SchemaSettingsSortField.tsx b/packages/core/client/src/schema-settings/SchemaSettingsSortField.tsx new file mode 100644 index 0000000000000..0e724ea79010b --- /dev/null +++ b/packages/core/client/src/schema-settings/SchemaSettingsSortField.tsx @@ -0,0 +1,61 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import { Field } from '@formily/core'; +import { useField, useFieldSchema } from '@formily/react'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { useTableBlockContext } from '../block-provider'; +import { useCollectionManager_deprecated } from '../collection-manager/hooks/useCollectionManager_deprecated'; +import { useCollection_deprecated } from '../collection-manager/hooks/useCollection_deprecated'; +import { useCompile } from '../schema-component/hooks/useCompile'; +import { useDesignable } from '../schema-component/hooks/useDesignable'; +import { SchemaSettingsSelectItem } from './SchemaSettings'; + +export function SchemaSettingsSortField() { + const { fields } = useCollection_deprecated(); + const field = useField(); + const fieldSchema = useFieldSchema(); + const { t } = useTranslation(); + const { dn } = useDesignable(); + const compile = useCompile(); + const { service, association } = useTableBlockContext(); + const { getCollectionJoinField } = useCollectionManager_deprecated(); + const collectionField = getCollectionJoinField(association); + const options = fields + .filter((field) => !field?.target && field.interface === 'sort') + .map((field) => { + return { + value: field?.name, + label: compile(field?.uiSchema?.title) || field?.name, + disabled: field?.scopeKey && collectionField?.foreignKey !== field.scopeKey, + }; + }); + + return ( + { + fieldSchema['x-decorator-props'].dragSortBy = dragSortBy; + service.run({ ...service.params?.[0], sort: dragSortBy }); + field.decoratorProps.dragSortBy = dragSortBy; + dn.emit('patch', { + schema: { + ['x-uid']: fieldSchema['x-uid'], + 'x-decorator-props': fieldSchema['x-decorator-props'], + }, + }); + dn.refresh(); + }} + /> + ); +} diff --git a/packages/core/client/src/schema-settings/SchemaSettingsTemplate.tsx b/packages/core/client/src/schema-settings/SchemaSettingsTemplate.tsx new file mode 100644 index 0000000000000..c0ff1716c3fb5 --- /dev/null +++ b/packages/core/client/src/schema-settings/SchemaSettingsTemplate.tsx @@ -0,0 +1,121 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import { FormLayout } from '@formily/antd-v5'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { useAPIClient } from '../api-client/hooks/useAPIClient'; +import { useCollectionManager_deprecated } from '../collection-manager/hooks/useCollectionManager_deprecated'; +import { useGlobalTheme } from '../global-theme'; +import { FormDialog } from '../schema-component/antd/form-dialog'; +import { FormItem } from '../schema-component/antd/form-item/FormItem'; +import { Input } from '../schema-component/antd/input/Input'; +import { SchemaComponent } from '../schema-component/core/SchemaComponent'; +import { useCompile } from '../schema-component/hooks/useCompile'; +import { createDesignable } from '../schema-component/hooks/useDesignable'; +import { useSchemaTemplateManager } from '../schema-templates'; +import { useBlockTemplateContext } from '../schema-templates/BlockTemplate'; +import { SchemaSettingsItem, useSchemaSettings } from './SchemaSettings'; + +export function SchemaSettingsTemplate(props) { + const { componentName, collectionName, resourceName, needRender } = props; + const { t } = useTranslation(); + const { getCollection } = useCollectionManager_deprecated(); + const { dn, setVisible, template, fieldSchema } = useSchemaSettings(); + const compile = useCompile(); + const api = useAPIClient(); + const { dn: tdn } = useBlockTemplateContext(); + const { saveAsTemplate, copyTemplateSchema } = useSchemaTemplateManager(); + const { theme } = useGlobalTheme(); + + if (!collectionName && !needRender) { + return null; + } + if (template) { + return ( + { + const schema = await copyTemplateSchema(template); + const removed = tdn.removeWithoutEmit(); + tdn.insertAfterEnd(schema, { + async onSuccess() { + await api.request({ + url: `/uiSchemas:remove/${removed['x-uid']}`, + }); + }, + }); + }} + > + {t('Convert reference to duplicate')} + + ); + } + return ( + { + setVisible(false); + const collection = collectionName && getCollection(collectionName); + const values = await FormDialog( + t('Save as template'), + () => { + return ( + + + + ); + }, + theme, + ).open({}); + const sdn = createDesignable({ + t, + api, + refresh: dn.refresh.bind(dn), + current: fieldSchema.parent, + }); + sdn.loadAPIClientEvents(); + const { key } = await saveAsTemplate({ + collectionName, + resourceName, + componentName, + dataSourceKey: collection.dataSource, + name: values.name, + uid: fieldSchema['x-uid'], + }); + sdn.removeWithoutEmit(fieldSchema); + sdn.insertBeforeEnd({ + type: 'void', + 'x-component': 'BlockTemplate', + 'x-component-props': { + templateId: key, + }, + }); + }} + > + {t('Save as template')} + + ); +} diff --git a/packages/core/client/src/schema-settings/index.ts b/packages/core/client/src/schema-settings/index.ts index f0178601b2450..0b153421d2076 100644 --- a/packages/core/client/src/schema-settings/index.ts +++ b/packages/core/client/src/schema-settings/index.ts @@ -11,15 +11,18 @@ export * from './DataTemplates/hooks/useCollectionState'; export * from './DataTemplates/utils'; export * from './GeneralSchemaDesigner'; export * from './SchemaSettings'; -export * from './hooks/useGetAriaLabelOfDesigner'; -export * from './hooks/useIsAllowToSetDefaultValue'; -export * from './isPatternDisabled'; +export * from './SchemaSettingsBlockTitleItem'; +export * from './SchemaSettingsConnectDataBlocks'; export * from './SchemaSettingsDataScope'; -export * from './SchemaSettingsDefaultValue'; export * from './SchemaSettingsDateFormat'; -export * from './SchemaSettingsSortingRule'; +export * from './SchemaSettingsDefaultValue'; export * from './SchemaSettingsNumberFormat'; +export * from './SchemaSettingsSortingRule'; +export * from './SchemaSettingsTemplate'; +export * from './hooks/useGetAriaLabelOfDesigner'; +export * from './hooks/useIsAllowToSetDefaultValue'; export { default as useParseDataScopeFilter } from './hooks/useParseDataScopeFilter'; +export * from './isPatternDisabled'; export { SchemaSettingsPlugin } from './SchemaSettingsPlugin'; export * from './VariableInput'; diff --git a/packages/plugins/@nocobase/plugin-map/src/client/block/MapBlock.Settings.tsx b/packages/plugins/@nocobase/plugin-map/src/client/block/MapBlock.Settings.tsx index acc5b164ba788..b32b68eb1b463 100644 --- a/packages/plugins/@nocobase/plugin-map/src/client/block/MapBlock.Settings.tsx +++ b/packages/plugins/@nocobase/plugin-map/src/client/block/MapBlock.Settings.tsx @@ -11,6 +11,7 @@ import { ISchema, useField, useFieldSchema } from '@formily/react'; import { FilterBlockType, FixedBlockDesignerItem, + SchemaSettings, SchemaSettingsBlockTitleItem, SchemaSettingsCascaderItem, SchemaSettingsConnectDataBlocks, @@ -19,13 +20,11 @@ import { SchemaSettingsModalItem, SchemaSettingsSelectItem, SchemaSettingsTemplate, + setDataLoadingModeSettingsItem, useCollection, + useCollectionManager_deprecated, useDesignable, useFormBlockContext, - SchemaSettings, - useCollectionManager_deprecated, - setDataLoadingModeSettingsItem, - useDataLoadingMode, } from '@nocobase/client'; import lodash from 'lodash'; import { useMapTranslation } from '../locale';