diff --git a/packages/core/client/src/application/__tests__/SchemaInitializer.test.ts b/packages/core/client/src/application/__tests__/SchemaInitializer.test.ts deleted file mode 100644 index e16ed381bd..0000000000 --- a/packages/core/client/src/application/__tests__/SchemaInitializer.test.ts +++ /dev/null @@ -1,83 +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 { SchemaInitializer } from '../schema-initializer/SchemaInitializer'; - -describe('SchemaInitializer', () => { - it('should initialize with default items when no options provided', () => { - const schema = new SchemaInitializer({ name: 'schema0' }); - expect(schema.items).toEqual([]); - }); - - it('should initialize with provided items', () => { - const schema = new SchemaInitializer({ type: 'item', items: [{ name: 'test', type: 'item' }], name: 'schema1' }); - expect(schema.items).toEqual([{ type: 'item', name: 'test' }]); - }); - - it('should add item with unique name', () => { - const schema = new SchemaInitializer({ items: [], name: 'schema2' }); - schema.add('item1', { type: 'item', test: true }); - expect(schema.items).toContainEqual({ type: 'item', name: 'item1', test: true }); - }); - - it('should replace item with same name', () => { - const schema = new SchemaInitializer({ - type: 'item', - items: [{ type: 'item', name: 'item1', test: false }], - name: 'schema3', - }); - schema.add('item1', { type: 'item', test: true }); - expect(schema.items).toContainEqual({ type: 'item', name: 'item1', test: true }); - expect(schema.items.length).toBe(1); - }); - - it('should add children to the specified parent item', () => { - const schema = new SchemaInitializer({ - type: 'item', - items: [{ type: 'item', name: 'parent', children: [] }], - name: 'schema4', - }); - schema.add('parent.child', { type: 'item', test: true }); - expect(schema.get('parent').children).toContainEqual({ type: 'item', name: 'child', test: true }); - }); - - it('should get the item by nested name', () => { - const schema = new SchemaInitializer({ - type: 'item', - items: [{ type: 'item', name: 'parent', children: [{ type: 'item', name: 'child', test: true }] }], - name: 'schema5', - }); - expect(schema.get('parent.child')).toEqual({ type: 'item', name: 'child', test: true }); - }); - - it('should return undefined for non-existent item', () => { - const schema = new SchemaInitializer({ type: 'item', items: [], name: 'schema6' }); - expect(schema.get('nonexistent')).toBeUndefined(); - }); - - it('should remove the specified item', () => { - const schema = new SchemaInitializer({ - type: 'item', - items: [{ type: 'item', name: 'toRemove', test: true }], - name: 'schema7', - }); - schema.remove('toRemove'); - expect(schema.items).not.toContainEqual({ type: 'item', name: 'toRemove', test: true }); - }); - - it('should remove the specified nested item', () => { - const schema = new SchemaInitializer({ - type: 'item', - items: [{ type: 'item', name: 'parent', children: [{ type: 'item', name: 'toRemove', test: true }] }], - name: 'schema8', - }); - schema.remove('parent.toRemove'); - expect(schema.get('parent').children).not.toContainEqual({ type: 'item', name: 'toRemove', test: true }); - }); -}); diff --git a/packages/core/client/src/application/__tests__/schema-initializer/SchemaInitializer.test.tsx b/packages/core/client/src/application/__tests__/schema-initializer/SchemaInitializer.test.tsx index 882ccddef2..ded6b27192 100644 --- a/packages/core/client/src/application/__tests__/schema-initializer/SchemaInitializer.test.tsx +++ b/packages/core/client/src/application/__tests__/schema-initializer/SchemaInitializer.test.tsx @@ -43,6 +43,23 @@ describe('SchemaInitializer', () => { }); }); + // 为了能让旧版插件代码正常工作(操作按钮拍平后:https://nocobase.feishu.cn/wiki/O7pjwSbBEigpOWkY9s5c03Yenkh),需要满足下面的测试用例 + test('add an item with nested name', () => { + // 等同于 initializer.add('item1', { title: 'item1 title' }); + initializer.add('parent.item1', { title: 'item1 title' }); + + // 等同于 initializer.get('item1') + expect(initializer.get('parent.item1')).toEqual({ + name: 'item1', + title: 'item1 title', + }); + expect(initializer.get('item1')).toEqual({ + name: 'item1', + title: 'item1 title', + }); + expect(initializer.get('parent')).toBe(undefined); + }); + test('updates a nested item if it already exists', () => { initializer.add('parent', { title: 'parent title' }); initializer.add('parent.item1', { title: 'title' }); diff --git a/packages/core/client/src/application/schema-initializer/CompatibleSchemaInitializer.tsx b/packages/core/client/src/application/schema-initializer/CompatibleSchemaInitializer.tsx index 6d01bfc255..adad508ea3 100644 --- a/packages/core/client/src/application/schema-initializer/CompatibleSchemaInitializer.tsx +++ b/packages/core/client/src/application/schema-initializer/CompatibleSchemaInitializer.tsx @@ -10,7 +10,7 @@ import { SchemaInitializer } from './SchemaInitializer'; /** - * @deprecated + * @deprecated - 该类仅用于兼容旧版 name,不推荐在新插件中使用 * * 因为需要把 SchemaInitializer 的 name 统一为一致的命名风格,统一之后新创建的 Schema 将 * 使用新的命名风格,而旧的 Schema 仍然使用旧的命名风格,这样会导致一些问题。所以需要有一个方法 @@ -99,7 +99,7 @@ const oldToNewNameMap = { /** * 由于旧版的 schema 的 x-initializer 的值是旧的命名风格,当其与新的命名比较时就存在问题, - * 这里通过将新版命名转换为旧版命名再进行比较,已解决这个问题。 + * 这里通过将新版命名转换为旧版命名再进行比较,以解决这个问题。 * @param oldOrNewName x-initializer 的值 * @param newName 新的命名 */ diff --git a/packages/core/client/src/application/schema-initializer/SchemaInitializer.tsx b/packages/core/client/src/application/schema-initializer/SchemaInitializer.tsx index bc31a13bb2..2625b25d02 100644 --- a/packages/core/client/src/application/schema-initializer/SchemaInitializer.tsx +++ b/packages/core/client/src/application/schema-initializer/SchemaInitializer.tsx @@ -24,14 +24,20 @@ export class SchemaInitializer { add(name: string, item: SchemaInitializerItemTypeWithoutName) { const arr = name.split('.'); - const data: any = { ...item, name: arr[arr.length - 1] }; - if (arr.length === 1) { + const itemName = arr[arr.length - 1]; + const data: any = { ...item, name: itemName }; + + const pushData = (name: string, data: any) => { const index = this.items.findIndex((item: any) => item.name === name); if (index === -1) { this.items.push(data); } else { this.items[index] = data; } + }; + + if (arr.length === 1) { + pushData(itemName, data); return; } @@ -48,25 +54,28 @@ export class SchemaInitializer { } else { parentItem.children[index] = data; } + + // 这里是为了兼容这个改动:https://nocobase.feishu.cn/wiki/O7pjwSbBEigpOWkY9s5c03Yenkh + } else { + pushData(itemName, data); } } get(nestedName: string): SchemaInitializerItemType | undefined { if (!nestedName) return undefined; const arr = nestedName.split('.'); - let current: any = this.items; + let current: any = { children: this.items }; for (let i = 0; i < arr.length; i++) { const name = arr[i]; - current = current.find((item) => item.name === name); - if (!current || i === arr.length - 1) { - return current; + const _current = current.children?.find((item) => item.name === name); + + if (_current) { + current = _current; } - if (current.children) { - current = current.children; - } else { - return undefined; + if (i === arr.length - 1) { + return _current; } } } diff --git a/packages/core/client/src/block-provider/FormBlockProvider.tsx b/packages/core/client/src/block-provider/FormBlockProvider.tsx index 043eeb28c8..a6fecd48b1 100644 --- a/packages/core/client/src/block-provider/FormBlockProvider.tsx +++ b/packages/core/client/src/block-provider/FormBlockProvider.tsx @@ -12,7 +12,6 @@ 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 { useCollection_deprecated } from '../collection-manager'; import { CollectionRecord, useCollectionManager, @@ -20,8 +19,8 @@ import { useCollectionRecord, } from '../data-source'; import { useTreeParentRecord } from '../modules/blocks/data-blocks/table/TreeRecordProvider'; -import { RecordProvider, useRecord } from '../record-provider'; -import { useActionContext, useDesignable } from '../schema-component'; +import { RecordProvider } from '../record-provider'; +import { useActionContext } from '../schema-component'; import { Templates as DataTemplateSelect } from '../schema-component/antd/form-v2/Templates'; import { BlockProvider, useBlockRequestContext } from './BlockProvider'; import { TemplateBlockProvider } from './TemplateBlockProvider'; @@ -125,27 +124,8 @@ export const useIsDetailBlock = () => { }; export const FormBlockProvider = withDynamicSchemaProps((props) => { - const record = useRecord(); const parentRecordData = useCollectionParentRecordData(); - const { collection, isCusomeizeCreate, parentRecord } = props; - const { __collection } = record; - const currentCollection = useCollection_deprecated(); - const { designable } = useDesignable(); - const isDetailBlock = useIsDetailBlock(); - let detailFlag = false; - if (isDetailBlock) { - detailFlag = true; - if (!designable && __collection) { - detailFlag = __collection === collection; - } - } - const createFlag = - (currentCollection.name === (collection?.name || collection) && !isDetailBlock) || - !currentCollection.name || - !collection; - if (!detailFlag && !createFlag && !isCusomeizeCreate) { - return null; - } + const { parentRecord } = props; return ( 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 d0f6b85fed..3d97353661 100644 --- a/packages/core/client/src/data-source/data-block/DataBlockProvider.tsx +++ b/packages/core/client/src/data-source/data-block/DataBlockProvider.tsx @@ -39,6 +39,8 @@ export interface AllDataBlockProps { requestService?: UseRequestService; requestOptions?: UseRequestOptions; dataLoadingMode?: 'auto' | 'manual'; + /** 如果为 true,则区块会被隐藏 */ + hidden?: boolean; [index: string]: any; } @@ -149,9 +151,13 @@ export const AssociationOrCollectionProvider = (props: { export const DataBlockProvider: FC = withDynamicSchemaProps( (props) => { - const { collection, association, dataSource, children, ...resets } = props as Partial; + const { collection, association, dataSource, children, hidden, ...resets } = props as Partial; const { dn } = useDesignable(); + if (hidden) { + return null; + } + return ( { const schema = { type: 'void', @@ -64,5 +64,5 @@ export const CreateChildInitializer = (props) => { }, }, }; - return ; + return ; }; diff --git a/packages/core/client/src/modules/actions/add-new/CreateActionInitializer.tsx b/packages/core/client/src/modules/actions/add-new/CreateActionInitializer.tsx index 19f6878c63..2e3f1b44e9 100644 --- a/packages/core/client/src/modules/actions/add-new/CreateActionInitializer.tsx +++ b/packages/core/client/src/modules/actions/add-new/CreateActionInitializer.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { useSchemaInitializerItem } from '../../../application'; -import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer'; +import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem'; export const CreateActionInitializer = () => { const schema = { @@ -67,5 +67,5 @@ export const CreateActionInitializer = () => { }, }; const itemConfig = useSchemaInitializerItem(); - return ; + return ; }; diff --git a/packages/core/client/src/modules/actions/add-new/createFormBlockInitializers.tsx b/packages/core/client/src/modules/actions/add-new/createFormBlockInitializers.tsx index a593a8f2ea..3089cf9b5b 100644 --- a/packages/core/client/src/modules/actions/add-new/createFormBlockInitializers.tsx +++ b/packages/core/client/src/modules/actions/add-new/createFormBlockInitializers.tsx @@ -7,15 +7,12 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ +import { useTranslation } from 'react-i18next'; import { CompatibleSchemaInitializer } from '../../../application/schema-initializer/CompatibleSchemaInitializer'; +import { useCollection } from '../../../data-source/collection/CollectionProvider'; import { gridRowColWrap } from '../../../schema-initializer/utils'; -/** - * @deprecated - * use `createFormBlockInitializers` instead - */ -export const createFormBlockInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'CreateFormBlockInitializers', +const commonOptions = { wrap: gridRowColWrap, title: '{{t("Add block")}}', icon: 'PlusOutlined', @@ -24,13 +21,36 @@ export const createFormBlockInitializers_deprecated = new CompatibleSchemaInitia type: 'itemGroup', title: '{{t("Data blocks")}}', name: 'dataBlocks', - children: [ - { - name: 'form', - title: '{{t("Form")}}', - Component: 'CreateFormBlockInitializer', - }, - ], + useChildren() { + const currentCollection = useCollection(); + const { t } = useTranslation(); + + return [ + { + name: 'form', + title: '{{t("Form")}}', + Component: 'FormBlockInitializer', + collectionName: currentCollection.name, + dataSource: currentCollection.dataSource, + componentProps: { + filterCollections({ collection, associationField }) { + if (associationField) { + return false; + } + if (collection.name === currentCollection.name) { + return true; + } + }, + showAssociationFields: true, + onlyCurrentDataSource: true, + hideSearch: true, + componentType: 'FormItem', + currentText: t('Current collection'), + otherText: t('Other collections'), + }, + }, + ]; + }, }, { type: 'itemGroup', @@ -45,40 +65,21 @@ export const createFormBlockInitializers_deprecated = new CompatibleSchemaInitia ], }, ], +}; + +/** + * @deprecated + * use `createFormBlockInitializers` instead + */ +export const createFormBlockInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'CreateFormBlockInitializers', + ...commonOptions, }); export const createFormBlockInitializers = new CompatibleSchemaInitializer( { name: 'popup:addNew:addBlock', - wrap: gridRowColWrap, - title: '{{t("Add block")}}', - icon: 'PlusOutlined', - items: [ - { - type: 'itemGroup', - title: '{{t("Data blocks")}}', - name: 'dataBlocks', - children: [ - { - name: 'form', - title: '{{t("Form")}}', - Component: 'CreateFormBlockInitializer', - }, - ], - }, - { - type: 'itemGroup', - title: '{{t("Other blocks")}}', - name: 'otherBlocks', - children: [ - { - name: 'markdown', - title: '{{t("Markdown")}}', - Component: 'MarkdownBlockInitializer', - }, - ], - }, - ], + ...commonOptions, }, createFormBlockInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/actions/add-record/CustomizeAddRecordActionInitializer.tsx b/packages/core/client/src/modules/actions/add-record/CustomizeAddRecordActionInitializer.tsx deleted file mode 100644 index bd316a5d05..0000000000 --- a/packages/core/client/src/modules/actions/add-record/CustomizeAddRecordActionInitializer.tsx +++ /dev/null @@ -1,68 +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 React from 'react'; -import { useSchemaInitializerItem } from '../../../application'; -import { BlockInitializer } from '../../../schema-initializer/items/BlockInitializer'; - -export const CustomizeAddRecordActionInitializer = () => { - const schema = { - type: 'void', - title: '{{t("Add record")}}', - 'x-toolbar': 'ActionSchemaToolbar', - 'x-settings': 'actionSettings:addRecord', - 'x-component': 'Action', - 'x-action': 'customize:create', - 'x-component-props': { - openMode: 'drawer', - icon: 'PlusOutlined', - }, - properties: { - drawer: { - type: 'void', - title: '{{t("Add record")}}', - 'x-component': 'Action.Container', - 'x-component-props': { - className: 'nb-action-popup', - }, - properties: { - tabs: { - type: 'void', - 'x-component': 'Tabs', - 'x-component-props': {}, - 'x-initializer': 'popup:addTab', - 'x-initializer-props': { - gridInitializer: 'popup:addRecord:addBlock', - }, - properties: { - tab1: { - type: 'void', - title: '{{t("Add record")}}', - 'x-component': 'Tabs.TabPane', - 'x-designer': 'Tabs.Designer', - 'x-component-props': {}, - properties: { - grid: { - type: 'void', - 'x-component': 'Grid', - 'x-initializer': 'popup:addRecord:addBlock', - properties: {}, - }, - }, - }, - }, - }, - }, - }, - }, - }; - const itemConfig = useSchemaInitializerItem(); - - return ; -}; diff --git a/packages/core/client/src/modules/actions/add-record/customizeCreateFormBlockInitializers.tsx b/packages/core/client/src/modules/actions/add-record/customizeCreateFormBlockInitializers.tsx index e291241a3e..56e51f4976 100644 --- a/packages/core/client/src/modules/actions/add-record/customizeCreateFormBlockInitializers.tsx +++ b/packages/core/client/src/modules/actions/add-record/customizeCreateFormBlockInitializers.tsx @@ -10,12 +10,7 @@ import { CompatibleSchemaInitializer } from '../../../application/schema-initializer/CompatibleSchemaInitializer'; import { gridRowColWrap } from '../../../schema-initializer/utils'; -/** - * @deprecated - * use `customizeCreateFormBlockInitializers` instead - */ -export const customizeCreateFormBlockInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'CusomeizeCreateFormBlockInitializers', +const commonOptions = { wrap: gridRowColWrap, title: '{{t("Add block")}}', icon: 'PlusOutlined', @@ -29,6 +24,7 @@ export const customizeCreateFormBlockInitializers_deprecated = new CompatibleSch name: 'form', title: '{{t("Form")}}', Component: 'FormBlockInitializer', + /** 表示是通过 Other collections 选项创建的区块(由于历史遗留问题,这里的命名暂不做更改) */ isCusomeizeCreate: true, }, ], @@ -46,41 +42,21 @@ export const customizeCreateFormBlockInitializers_deprecated = new CompatibleSch ], }, ], +}; + +/** + * @deprecated + * use `customizeCreateFormBlockInitializers` instead + */ +export const customizeCreateFormBlockInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'CusomeizeCreateFormBlockInitializers', + ...commonOptions, }); export const customizeCreateFormBlockInitializers = new CompatibleSchemaInitializer( { name: 'popup:addRecord:addBlock', - wrap: gridRowColWrap, - title: '{{t("Add block")}}', - icon: 'PlusOutlined', - items: [ - { - type: 'itemGroup', - title: '{{t("Data blocks")}}', - name: 'dataBlocks', - children: [ - { - name: 'form', - title: '{{t("Form")}}', - Component: 'FormBlockInitializer', - isCusomeizeCreate: true, - }, - ], - }, - { - type: 'itemGroup', - title: '{{t("Other blocks")}}', - name: 'otherBlocks', - children: [ - { - name: 'markdown', - title: '{{t("Markdown")}}', - Component: 'MarkdownBlockInitializer', - }, - ], - }, - ], + ...commonOptions, }, customizeCreateFormBlockInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/actions/bulk-destroy/BulkDestroyActionInitializer.tsx b/packages/core/client/src/modules/actions/bulk-destroy/BulkDestroyActionInitializer.tsx index e478f52310..8b516751fe 100644 --- a/packages/core/client/src/modules/actions/bulk-destroy/BulkDestroyActionInitializer.tsx +++ b/packages/core/client/src/modules/actions/bulk-destroy/BulkDestroyActionInitializer.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { useCollection_deprecated } from '../../../collection-manager'; - import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer'; export const BulkDestroyActionInitializer = (props) => { diff --git a/packages/core/client/src/modules/actions/delete/DestroyActionInitializer.tsx b/packages/core/client/src/modules/actions/delete/DestroyActionInitializer.tsx index 6429f3446e..4380ded4a4 100644 --- a/packages/core/client/src/modules/actions/delete/DestroyActionInitializer.tsx +++ b/packages/core/client/src/modules/actions/delete/DestroyActionInitializer.tsx @@ -8,7 +8,6 @@ */ import React from 'react'; - import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer'; export const DestroyActionInitializer = (props) => { diff --git a/packages/core/client/src/modules/actions/disassociate/DisassociateActionInitializer.tsx b/packages/core/client/src/modules/actions/disassociate/DisassociateActionInitializer.tsx index 33f4e7a890..397f45e2ec 100644 --- a/packages/core/client/src/modules/actions/disassociate/DisassociateActionInitializer.tsx +++ b/packages/core/client/src/modules/actions/disassociate/DisassociateActionInitializer.tsx @@ -8,8 +8,7 @@ */ import React from 'react'; - -import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer'; +import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem'; export const DisassociateActionInitializer = (props) => { const schema = { @@ -31,5 +30,5 @@ export const DisassociateActionInitializer = (props) => { triggerWorkflows: [], }, }; - return ; + return ; }; diff --git a/packages/core/client/src/modules/actions/filter/FilterActionInitializer.tsx b/packages/core/client/src/modules/actions/filter/FilterActionInitializer.tsx index c4bbc2a47b..090fab4dc8 100644 --- a/packages/core/client/src/modules/actions/filter/FilterActionInitializer.tsx +++ b/packages/core/client/src/modules/actions/filter/FilterActionInitializer.tsx @@ -8,7 +8,6 @@ */ import React from 'react'; - import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer'; export const FilterActionInitializer = (props) => { diff --git a/packages/core/client/src/modules/actions/save-record/SaveRecordActionInitializer.tsx b/packages/core/client/src/modules/actions/save-record/SaveRecordActionInitializer.tsx deleted file mode 100644 index 89ce519b94..0000000000 --- a/packages/core/client/src/modules/actions/save-record/SaveRecordActionInitializer.tsx +++ /dev/null @@ -1,40 +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 React from 'react'; -import { BlockInitializer } from '../../../schema-initializer/items'; -import { useSchemaInitializerItem } from '../../../application'; - -export const SaveRecordActionInitializer = () => { - const schema = { - title: '{{ t("Save record") }}', - 'x-action': 'customize:save', - 'x-component': 'Action', - 'x-use-component-props': 'useCreateActionProps', - 'x-toolbar': 'ActionSchemaToolbar', - 'x-settings': 'actionSettings:saveRecord', - 'x-designer-props': { - modalTip: - '{{ t("When the button is clicked, the following fields will be assigned and saved together with the fields in the form. If there are overlapping fields, the value here will overwrite the value in the form.") }}', - }, - 'x-action-settings': { - assignedValues: {}, - skipValidator: false, - onSuccess: { - manualClose: true, - redirecting: false, - successMessage: '{{t("Submitted successfully")}}', - }, - triggerWorkflows: [], - }, - }; - - const itemConfig = useSchemaInitializerItem(); - return ; -}; diff --git a/packages/core/client/src/modules/actions/save-record/customizeSaveRecordActionSettings.tsx b/packages/core/client/src/modules/actions/save-record/customizeSaveRecordActionSettings.tsx index b9921c3d6f..87eaf97dcd 100644 --- a/packages/core/client/src/modules/actions/save-record/customizeSaveRecordActionSettings.tsx +++ b/packages/core/client/src/modules/actions/save-record/customizeSaveRecordActionSettings.tsx @@ -15,13 +15,17 @@ import { AfterSuccess, AssignedFieldValues, ButtonEditor, + RefreshDataBlockRequest, RemoveButton, SecondConFirm, SkipValidation, WorkflowConfig, - RefreshDataBlockRequest, } from '../../../schema-component/antd/action/Action.Designer'; +/** + * @deprecated + * 已废弃,继续保留是为了兼容旧版本的 Schema,会在后面的版本中移除 + */ export const customizeSaveRecordActionSettings = new SchemaSettings({ name: 'actionSettings:saveRecord', items: [ diff --git a/packages/core/client/src/modules/actions/submit/CreateSubmitActionInitializer.tsx b/packages/core/client/src/modules/actions/submit/CreateSubmitActionInitializer.tsx index a95b7dcba1..2b4127eb86 100644 --- a/packages/core/client/src/modules/actions/submit/CreateSubmitActionInitializer.tsx +++ b/packages/core/client/src/modules/actions/submit/CreateSubmitActionInitializer.tsx @@ -8,7 +8,7 @@ */ import React from 'react'; -import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer'; +import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem'; export const CreateSubmitActionInitializer = (props) => { const schema = { @@ -26,5 +26,5 @@ export const CreateSubmitActionInitializer = (props) => { triggerWorkflows: [], }, }; - return ; + return ; }; diff --git a/packages/core/client/src/modules/actions/submit/UpdateSubmitActionInitializer.tsx b/packages/core/client/src/modules/actions/submit/UpdateSubmitActionInitializer.tsx index 67b5ff1beb..ab3fe17889 100644 --- a/packages/core/client/src/modules/actions/submit/UpdateSubmitActionInitializer.tsx +++ b/packages/core/client/src/modules/actions/submit/UpdateSubmitActionInitializer.tsx @@ -8,8 +8,7 @@ */ import React from 'react'; - -import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer'; +import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem'; export const UpdateSubmitActionInitializer = (props) => { const schema = { @@ -28,5 +27,5 @@ export const UpdateSubmitActionInitializer = (props) => { triggerWorkflows: [], }, }; - return ; + return ; }; diff --git a/packages/core/client/src/modules/actions/submit/createSubmitActionSettings.tsx b/packages/core/client/src/modules/actions/submit/createSubmitActionSettings.tsx index 4f2662e1e5..a7756c36f3 100644 --- a/packages/core/client/src/modules/actions/submit/createSubmitActionSettings.tsx +++ b/packages/core/client/src/modules/actions/submit/createSubmitActionSettings.tsx @@ -7,22 +7,26 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { useFieldSchema, useField, connect, mapProps, ISchema } from '@formily/react'; +import { ISchema, connect, mapProps, useField, useFieldSchema } from '@formily/react'; import { isValid } from '@formily/shared'; -import React, { useEffect, useState } from 'react'; import { Tree as AntdTree } from 'antd'; +import React, { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import { useSchemaToolbar } from '../../../application'; import { SchemaSettings } from '../../../application/schema-settings/SchemaSettings'; +import { useCollection_deprecated } from '../../../collection-manager'; +import { useDesignable } from '../../../schema-component'; import { + AfterSuccess, + AssignedFieldValues, ButtonEditor, + RefreshDataBlockRequest, RemoveButton, SecondConFirm, + SkipValidation, WorkflowConfig, } from '../../../schema-component/antd/action/Action.Designer'; -import { useTranslation } from 'react-i18next'; -import { useDesignable } from '../../../schema-component'; import { useCollectionState } from '../../../schema-settings/DataTemplates/hooks/useCollectionState'; -import { useCollection_deprecated } from '../../../collection-manager'; import { SchemaSettingsModalItem } from '../../../schema-settings/SchemaSettings'; const Tree = connect( @@ -132,6 +136,7 @@ export function SaveMode() { /> ); } + export const createSubmitActionSettings = new SchemaSettings({ name: 'actionSettings:createSubmit', items: [ @@ -159,6 +164,31 @@ export const createSubmitActionSettings = new SchemaSettings({ name: 'saveMode', Component: SaveMode, }, + { + name: 'assignFieldValues', + Component: AssignedFieldValues, + }, + { + name: 'skipRequiredValidation', + Component: SkipValidation, + }, + { + name: 'afterSuccessfulSubmission', + Component: AfterSuccess, + useVisible() { + const fieldSchema = useFieldSchema(); + return isValid(fieldSchema?.['x-action-settings']?.onSuccess); + }, + }, + { + name: 'refreshDataBlockRequest', + Component: RefreshDataBlockRequest, + useComponentProps() { + return { + isPopupAction: false, + }; + }, + }, { name: 'remove', sort: 100, diff --git a/packages/core/client/src/modules/actions/submit/updateSubmitActionSettings.tsx b/packages/core/client/src/modules/actions/submit/updateSubmitActionSettings.tsx index 2e20e1ab6b..ff2a3a95a9 100644 --- a/packages/core/client/src/modules/actions/submit/updateSubmitActionSettings.tsx +++ b/packages/core/client/src/modules/actions/submit/updateSubmitActionSettings.tsx @@ -12,9 +12,13 @@ import { isValid } from '@formily/shared'; import { isInitializersSame, useSchemaToolbar } from '../../../application'; import { SchemaSettings } from '../../../application/schema-settings/SchemaSettings'; import { + AfterSuccess, + AssignedFieldValues, ButtonEditor, + RefreshDataBlockRequest, RemoveButton, SecondConFirm, + SkipValidation, WorkflowConfig, } from '../../../schema-component/antd/action/Action.Designer'; import { SaveMode } from './createSubmitActionSettings'; @@ -42,6 +46,31 @@ export const updateSubmitActionSettings = new SchemaSettings({ return isValid(fieldSchema?.['x-action-settings']?.triggerWorkflows); }, }, + { + name: 'assignFieldValues', + Component: AssignedFieldValues, + }, + { + name: 'skipRequiredValidation', + Component: SkipValidation, + }, + { + name: 'afterSuccessfulSubmission', + Component: AfterSuccess, + useVisible() { + const fieldSchema = useFieldSchema(); + return isValid(fieldSchema?.['x-action-settings']?.onSuccess); + }, + }, + { + name: 'refreshDataBlockRequest', + Component: RefreshDataBlockRequest, + useComponentProps() { + return { + isPopupAction: false, + }; + }, + }, { name: 'remove', sort: 100, diff --git a/packages/core/client/src/modules/actions/view-edit-popup/UpdateActionInitializer.tsx b/packages/core/client/src/modules/actions/view-edit-popup/UpdateActionInitializer.tsx index 1f4d694255..195240ff3f 100644 --- a/packages/core/client/src/modules/actions/view-edit-popup/UpdateActionInitializer.tsx +++ b/packages/core/client/src/modules/actions/view-edit-popup/UpdateActionInitializer.tsx @@ -8,8 +8,7 @@ */ import React from 'react'; - -import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer'; +import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem'; export const UpdateActionInitializer = (props) => { const schema = { @@ -59,5 +58,5 @@ export const UpdateActionInitializer = (props) => { }, }, }; - return ; + return ; }; diff --git a/packages/core/client/src/modules/actions/view-edit-popup/ViewActionInitializer.tsx b/packages/core/client/src/modules/actions/view-edit-popup/ViewActionInitializer.tsx index 1d1cf0015e..b86028e2b2 100644 --- a/packages/core/client/src/modules/actions/view-edit-popup/ViewActionInitializer.tsx +++ b/packages/core/client/src/modules/actions/view-edit-popup/ViewActionInitializer.tsx @@ -8,8 +8,7 @@ */ import React from 'react'; - -import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer'; +import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem'; export const ViewActionInitializer = (props) => { const schema = { @@ -58,5 +57,5 @@ export const ViewActionInitializer = (props) => { }, }, }; - return ; + return ; }; diff --git a/packages/core/client/src/modules/blocks/data-blocks/details-multi/DetailsActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/details-multi/DetailsActionInitializers.tsx index 009c097735..b6ad3b6254 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/details-multi/DetailsActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/details-multi/DetailsActionInitializers.tsx @@ -9,13 +9,7 @@ import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer'; -/** - * @deprecated - * use `detailsActionInitializers` instead - * 表单的操作配置 - */ -export const detailsActionInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'DetailsActionInitializers', +const commonOptions = { title: '{{t("Configure actions")}}', icon: 'SettingOutlined', style: { @@ -50,17 +44,17 @@ export const detailsActionInitializers_deprecated = new CompatibleSchemaInitiali }, ], }, - { - name: 'divider', - type: 'divider', - }, - { - type: 'subMenu', - name: 'customize', - title: '{{t("Customize")}}', - children: [], - }, ], +}; + +/** + * @deprecated + * use `detailsActionInitializers` instead + * 表单的操作配置 + */ +export const detailsActionInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'DetailsActionInitializers', + ...commonOptions, }); /** @@ -70,41 +64,7 @@ export const detailsActionInitializers_deprecated = new CompatibleSchemaInitiali export const detailsActionInitializers = new CompatibleSchemaInitializer( { name: 'detailsWithPaging:configureActions', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'itemGroup', - title: '{{t("Enable actions")}}', - name: 'enableActions', - children: [ - { - name: 'edit', - title: '{{t("Edit")}}', - Component: 'UpdateActionInitializer', - schema: { - 'x-component': 'Action', - 'x-decorator': 'ACLActionProvider', - 'x-component-props': { - type: 'primary', - }, - }, - }, - { - name: 'delete', - title: '{{t("Delete")}}', - Component: 'DestroyActionInitializer', - schema: { - 'x-component': 'Action', - 'x-decorator': 'ACLActionProvider', - }, - }, - ], - }, - ], + ...commonOptions, }, detailsActionInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/blocks/data-blocks/details-multi/__e2e__/schemaInitializer.test.ts b/packages/core/client/src/modules/blocks/data-blocks/details-multi/__e2e__/schemaInitializer.test.ts index 1530e1694a..9a251e9dec 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/details-multi/__e2e__/schemaInitializer.test.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/details-multi/__e2e__/schemaInitializer.test.ts @@ -7,9 +7,16 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { createBlockInPage, expect, oneEmptyDetailsBlock, test } from '@nocobase/test/e2e'; +import { Page, createBlockInPage, expect, oneEmptyDetailsBlock, test } from '@nocobase/test/e2e'; import { oneEmptyTableWithUsers } from './templatesOfBug'; +const deleteButton = async (page: Page, name: string) => { + await page.getByRole('button', { name }).hover(); + await page.getByRole('button', { name }).getByLabel('designer-schema-settings-').hover(); + await page.getByRole('menuitem', { name: 'Delete' }).click(); + await page.getByRole('button', { name: 'OK', exact: true }).click(); +}; + test.describe('where multi data details block can be added', () => { test('page', async ({ page, mockPage }) => { await mockPage().goto(); @@ -109,20 +116,13 @@ test.describe('configure actions', () => { await page.getByRole('menuitem', { name: 'Edit' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click(); - await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).toBeChecked(); - await page.mouse.move(300, 0); await expect(page.getByRole('button', { name: 'Edit' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Delete' })).toBeVisible(); // delete buttons - await page.getByLabel('schema-initializer-ActionBar-detailsWithPaging:configureActions-general').hover(); - await page.getByRole('menuitem', { name: 'Edit' }).click(); - await page.getByRole('menuitem', { name: 'Delete' }).click(); - - await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).not.toBeChecked(); + await deleteButton(page, 'Edit'); + await deleteButton(page, 'Delete'); await page.mouse.move(300, 0); await expect(page.getByRole('button', { name: 'Edit' })).not.toBeVisible(); diff --git a/packages/core/client/src/modules/blocks/data-blocks/details-single/ReadPrettyFormActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/details-single/ReadPrettyFormActionInitializers.tsx index 0ff48397f9..09effc3712 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/details-single/ReadPrettyFormActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/details-single/ReadPrettyFormActionInitializers.tsx @@ -15,13 +15,7 @@ const useVisibleCollection = () => { return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; }; -/** - * @deprecated - * use `readPrettyFormActionInitializers` instead - * 表单的操作配置 - */ -export const readPrettyFormActionInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'ReadPrettyFormActionInitializers', +const commonOptions = { title: '{{t("Configure actions")}}', icon: 'SettingOutlined', style: { @@ -29,154 +23,72 @@ export const readPrettyFormActionInitializers_deprecated = new CompatibleSchemaI }, items: [ { - type: 'itemGroup', - name: 'enableActions', - title: '{{t("Enable actions")}}', - children: [ - { - title: '{{t("Edit")}}', - name: 'edit', - Component: 'UpdateActionInitializer', - schema: { - 'x-component': 'Action', - 'x-decorator': 'ACLActionProvider', - 'x-component-props': { - type: 'primary', - }, - }, - useVisible: useVisibleCollection, + title: '{{t("Edit")}}', + name: 'edit', + Component: 'UpdateActionInitializer', + schema: { + 'x-component': 'Action', + 'x-decorator': 'ACLActionProvider', + 'x-component-props': { + type: 'primary', }, - { - title: '{{t("Delete")}}', - name: 'delete', - Component: 'DestroyActionInitializer', - schema: { - 'x-component': 'Action', - 'x-decorator': 'ACLActionProvider', - }, - useVisible: useVisibleCollection, - }, - ], + }, + useVisible: useVisibleCollection, }, { - name: 'divider', - type: 'divider', + title: '{{t("Delete")}}', + name: 'delete', + Component: 'DestroyActionInitializer', + schema: { + 'x-component': 'Action', + 'x-decorator': 'ACLActionProvider', + }, + useVisible: useVisibleCollection, }, { - type: 'subMenu', - name: 'customize', - title: '{{t("Customize")}}', - children: [ - { - name: 'popup', - title: '{{t("Popup")}}', - Component: 'PopupActionInitializer', - useComponentProps() { - return { - 'x-component': 'Action', - }; - }, - }, - { - name: 'updateRecord', - title: '{{t("Update record")}}', - Component: 'UpdateRecordActionInitializer', - useComponentProps() { - return { - 'x-component': 'Action', - }; - }, - useVisible: useVisibleCollection, - }, - { - name: 'customRequest', - title: '{{t("Custom request")}}', - Component: 'CustomRequestInitializer', - useVisible: useVisibleCollection, - }, - ], + name: 'popup', + title: '{{t("Popup")}}', + Component: 'PopupActionInitializer', + useComponentProps() { + return { + 'x-component': 'Action', + }; + }, + }, + { + name: 'updateRecord', + title: '{{t("Update record")}}', + Component: 'UpdateRecordActionInitializer', + useComponentProps() { + return { + 'x-component': 'Action', + }; + }, + useVisible: useVisibleCollection, + }, + { + name: 'customRequest', + title: '{{t("Custom request")}}', + Component: 'CustomRequestInitializer', + useVisible: useVisibleCollection, }, ], +}; + +/** + * @deprecated + * use `readPrettyFormActionInitializers` instead + * 表单的操作配置 + */ +export const readPrettyFormActionInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'ReadPrettyFormActionInitializers', + ...commonOptions, }); export const readPrettyFormActionInitializers = new CompatibleSchemaInitializer( { name: 'details:configureActions', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'itemGroup', - name: 'enableActions', - title: '{{t("Enable actions")}}', - children: [ - { - title: '{{t("Edit")}}', - name: 'edit', - Component: 'UpdateActionInitializer', - schema: { - 'x-component': 'Action', - 'x-decorator': 'ACLActionProvider', - 'x-component-props': { - type: 'primary', - }, - }, - useVisible: useVisibleCollection, - }, - { - title: '{{t("Delete")}}', - name: 'delete', - Component: 'DestroyActionInitializer', - schema: { - 'x-component': 'Action', - 'x-decorator': 'ACLActionProvider', - }, - useVisible: useVisibleCollection, - }, - ], - }, - { - name: 'divider', - type: 'divider', - }, - { - type: 'subMenu', - name: 'customize', - title: '{{t("Customize")}}', - children: [ - { - name: 'popup', - title: '{{t("Popup")}}', - Component: 'PopupActionInitializer', - useComponentProps() { - return { - 'x-component': 'Action', - }; - }, - }, - { - name: 'updateRecord', - title: '{{t("Update record")}}', - Component: 'UpdateRecordActionInitializer', - useComponentProps() { - return { - 'x-component': 'Action', - }; - }, - useVisible: useVisibleCollection, - }, - { - name: 'customRequest', - title: '{{t("Custom request")}}', - Component: 'CustomRequestInitializer', - useVisible: useVisibleCollection, - }, - ], - }, - ], + ...commonOptions, }, readPrettyFormActionInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/blocks/data-blocks/details-single/ReadPrettyFormItemInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/details-single/ReadPrettyFormItemInitializers.tsx index 29516b4095..b47af5d54e 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/details-single/ReadPrettyFormItemInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/details-single/ReadPrettyFormItemInitializers.tsx @@ -54,12 +54,7 @@ const AssociatedFields = () => { return {schema}; }; -/** - * @deprecated - * use `readPrettyFormItemInitializers` instead - */ -export const readPrettyFormItemInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'ReadPrettyFormItemInitializers', +const commonOptions = { wrap: gridRowColWrap, icon: 'SettingOutlined', title: '{{t("Configure fields")}}', @@ -100,51 +95,21 @@ export const readPrettyFormItemInitializers_deprecated = new CompatibleSchemaIni }, }, ], +}; + +/** + * @deprecated + * use `readPrettyFormItemInitializers` instead + */ +export const readPrettyFormItemInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'ReadPrettyFormItemInitializers', + ...commonOptions, }); export const readPrettyFormItemInitializers = new CompatibleSchemaInitializer( { name: 'details:configureFields', - wrap: gridRowColWrap, - icon: 'SettingOutlined', - title: '{{t("Configure fields")}}', - items: [ - { - type: 'itemGroup', - name: 'displayFields', - title: '{{t("Display fields")}}', - useChildren: useFormItemInitializerFields, - }, - { - name: 'parentCollectionFields', - Component: ParentCollectionFields, - }, - { - name: 'associationFields', - Component: AssociatedFields, - }, - { - name: 'divider', - type: 'divider', - }, - { - name: 'addText', - title: '{{t("Add text")}}', - Component: 'BlockItemInitializer', - schema: { - type: 'void', - 'x-editable': false, - 'x-decorator': 'FormItem', - // 'x-designer': 'Markdown.Void.Designer', - 'x-toolbar': 'FormItemSchemaToolbar', - 'x-settings': 'blockSettings:markdown', - 'x-component': 'Markdown.Void', - 'x-component-props': { - content: '{{t("This is a demo text, **supports Markdown syntax**.")}}', - }, - }, - }, - ], + ...commonOptions, }, readPrettyFormItemInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/blocks/data-blocks/details-single/__e2e__/schemaInitializer.test.ts b/packages/core/client/src/modules/blocks/data-blocks/details-single/__e2e__/schemaInitializer.test.ts index 45e2c4bf32..284fe0135e 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/details-single/__e2e__/schemaInitializer.test.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/details-single/__e2e__/schemaInitializer.test.ts @@ -143,13 +143,11 @@ test.describe('configure fields', () => {}); async function createAction(page: Page, name: string) { await page.getByLabel('schema-initializer-ActionBar-details:configureActions-general').hover(); await page.getByRole('menuitem', { name: name }).click(); - await expect(page.getByRole('menuitem', { name: name }).getByRole('switch')).toBeChecked(); await page.mouse.move(300, 0); } async function createCustomAction(page: Page, name: string) { await page.getByLabel('schema-initializer-ActionBar-details:configureActions-general').hover(); - await page.getByRole('menuitem', { name: 'Customize' }).hover(); await page.getByRole('menuitem', { name: name }).click(); await page.mouse.move(0, 400); } diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/CreateFormBlockInitializer.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/CreateFormBlockInitializer.tsx deleted file mode 100644 index 3082c6aa19..0000000000 --- a/packages/core/client/src/modules/blocks/data-blocks/form/CreateFormBlockInitializer.tsx +++ /dev/null @@ -1,75 +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 { FormOutlined } from '@ant-design/icons'; -import React from 'react'; - -import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../../../application'; -import { useCollection_deprecated } from '../../../../collection-manager'; -import { useRecordCollectionDataSourceItems } from '../../../../schema-initializer/utils'; -import { useSchemaTemplateManager } from '../../../../schema-templates'; -import { createCreateFormBlockUISchema } from './createCreateFormBlockUISchema'; -import { useAssociationName } from '../../../../data-source'; - -// TODO: `SchemaInitializerItem` items -export const CreateFormBlockInitializer = () => { - const itemConfig = useSchemaInitializerItem(); - const { onCreateBlockSchema, componentType, createBlockSchema, ...others } = itemConfig; - const { getTemplateSchemaByMode } = useSchemaTemplateManager(); - const { insert } = useSchemaInitializer(); - const association = useAssociationName(); - const collection = useCollection_deprecated(); - return ( - } - {...others} - onClick={async ({ item }) => { - if (item.template) { - const s = await getTemplateSchemaByMode(item); - if (item.template.componentName === 'FormItem') { - const blockSchema = createCreateFormBlockUISchema( - association - ? { - association, - dataSource: collection.dataSource, - templateSchema: s, - } - : { - collectionName: collection.name, - dataSource: collection.dataSource, - templateSchema: s, - }, - ); - if (item.mode === 'reference') { - blockSchema['x-template-key'] = item.template.key; - } - insert(blockSchema); - } else { - insert(s); - } - } else { - insert( - createCreateFormBlockUISchema( - association - ? { - association, - dataSource: collection.dataSource, - } - : { - collectionName: collection.name, - dataSource: collection.dataSource, - }, - ), - ); - } - }} - items={useRecordCollectionDataSourceItems('FormItem')} - /> - ); -}; diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/FormBlockInitializer.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/FormBlockInitializer.tsx index e233b22444..eb2aba6ffe 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/FormBlockInitializer.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/form/FormBlockInitializer.tsx @@ -10,6 +10,7 @@ import { FormOutlined } from '@ant-design/icons'; import React, { useCallback } from 'react'; import { useSchemaInitializer, useSchemaInitializerItem } from '../../../../application'; +import { useAssociationName } from '../../../../data-source/collection/AssociationProvider'; import { Collection, CollectionFieldOptions } from '../../../../data-source/collection/Collection'; import { DataBlockInitializer } from '../../../../schema-initializer/items/DataBlockInitializer'; import { createCreateFormBlockUISchema } from './createCreateFormBlockUISchema'; @@ -24,6 +25,8 @@ export const FormBlockInitializer = ({ showAssociationFields, hideChildrenIfSingleCollection, hideOtherRecordsInPopup, + currentText, + otherText, }: { filterCollections: (options: { collection?: Collection; associationField?: CollectionFieldOptions }) => boolean; onlyCurrentDataSource: boolean; @@ -47,6 +50,10 @@ export const FormBlockInitializer = ({ * 隐藏弹窗中的 Other records 选项 */ hideOtherRecordsInPopup?: boolean; + /** 用于更改 Current record 的文案 */ + currentText?: string; + /** 用于更改 Other records 的文案 */ + otherText?: string; }) => { const itemConfig = useSchemaInitializerItem(); const { createFormBlock, templateWrap } = useCreateFormBlock(); @@ -84,42 +91,84 @@ export const FormBlockInitializer = ({ showAssociationFields={showAssociationFields} hideChildrenIfSingleCollection={hideChildrenIfSingleCollection} hideOtherRecordsInPopup={hideOtherRecordsInPopup} + currentText={currentText} + otherText={otherText} /> ); }; export const useCreateFormBlock = () => { const { insert } = useSchemaInitializer(); - const itemConfig = useSchemaInitializerItem(); - const { isCusomeizeCreate: isCustomizeCreate } = itemConfig; + const association = useAssociationName(); + const { isCusomeizeCreate: isCustomizeCreate } = useSchemaInitializerItem(); const createFormBlock = useCallback( - ({ item }) => { - insert( - createCreateFormBlockUISchema({ - collectionName: item.collectionName || item.name, - dataSource: item.dataSource, - isCusomeizeCreate: isCustomizeCreate, - }), - ); + ({ item, fromOthersInPopup }) => { + if (fromOthersInPopup) { + insert( + createCreateFormBlockUISchema({ + collectionName: item.collectionName || item.name, + dataSource: item.dataSource, + isCusomeizeCreate: true, + }), + ); + } else { + insert( + createCreateFormBlockUISchema( + association + ? { + association, + dataSource: item.dataSource, + isCusomeizeCreate: isCustomizeCreate, + } + : { + collectionName: item.collectionName || item.name, + dataSource: item.dataSource, + isCusomeizeCreate: isCustomizeCreate, + }, + ), + ); + } }, - [insert, isCustomizeCreate], + [association, insert, isCustomizeCreate], ); const templateWrap = useCallback( - (templateSchema, { item }) => { - const schema = createCreateFormBlockUISchema({ - isCusomeizeCreate: isCustomizeCreate, - dataSource: item.dataSource, - templateSchema: templateSchema, - collectionName: item.name, - }); + (templateSchema, { item, fromOthersInPopup }) => { + let schema; + + if (fromOthersInPopup) { + schema = createCreateFormBlockUISchema({ + dataSource: item.dataSource, + templateSchema: templateSchema, + collectionName: item.name, + isCusomeizeCreate: true, + }); + } else { + schema = createCreateFormBlockUISchema( + association + ? { + dataSource: item.dataSource, + templateSchema: templateSchema, + collectionName: item.name, + association, + isCusomeizeCreate: isCustomizeCreate, + } + : { + dataSource: item.dataSource, + templateSchema: templateSchema, + collectionName: item.name, + isCusomeizeCreate: isCustomizeCreate, + }, + ); + } + if (item.template && item.mode === 'reference') { schema['x-template-key'] = item.template.key; } return schema; }, - [isCustomizeCreate], + [association, isCustomizeCreate], ); return { diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/associationForm.test.ts b/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/associationForm.test.ts index ff1e4a5dd9..073ac924c1 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/associationForm.test.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/associationForm.test.ts @@ -62,7 +62,8 @@ test.describe('association form block', () => { .getByLabel('schema-initializer-Grid-popup') .click(); - await page.getByRole('menuitem', { name: 'form Form' }).click(); + await page.getByRole('menuitem', { name: 'form Form' }).hover(); + await page.getByRole('menuitem', { name: 'Current collection' }).click(); await expect(await page.getByLabel('block-item-CardItem-roles-form')).toBeVisible(); }); }); diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/schemaInitializer.test.ts b/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/schemaInitializer.test.ts index 6c164f2d3f..3f4ce43362 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/schemaInitializer.test.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/schemaInitializer.test.ts @@ -8,10 +8,17 @@ */ import { uid } from '@formily/shared'; -import { createBlockInPage, expect, oneEmptyForm, test } from '@nocobase/test/e2e'; +import { Page, createBlockInPage, expect, oneEmptyForm, test } from '@nocobase/test/e2e'; import { oneEmptyTableWithUsers } from '../../../details-multi/__e2e__/templatesOfBug'; import { T3106, T3469, oneFormWithInheritFields } from './templatesOfBug'; +const deleteButton = async (page: Page, name: string) => { + await page.getByRole('button', { name }).hover(); + await page.getByRole('button', { name }).getByLabel('designer-schema-settings-').hover(); + await page.getByRole('menuitem', { name: 'Delete' }).click(); + await page.getByRole('button', { name: 'OK', exact: true }).click(); +}; + test.describe('where creation form block can be added', () => { test('page', async ({ page, mockPage }) => { await mockPage().goto(); @@ -111,16 +118,11 @@ test.describe('configure actions', () => { // add button await page.getByRole('menuitem', { name: 'Submit' }).click(); - await expect(page.getByRole('menuitem', { name: 'Submit' }).getByRole('switch')).toBeChecked(); - await page.mouse.move(300, 0); await expect(page.getByRole('button', { name: 'Submit' })).toBeVisible(); // delete button - await page.getByLabel('schema-initializer-ActionBar-createForm:configureActions-general').hover(); - await page.getByRole('menuitem', { name: 'Submit' }).click(); - await expect(page.getByRole('menuitem', { name: 'Submit' }).getByRole('switch')).not.toBeChecked(); - + await deleteButton(page, 'Submit'); await page.mouse.move(300, 0); await expect(page.getByRole('button', { name: 'Submit' })).not.toBeVisible(); }); @@ -178,14 +180,4 @@ test.describe('configure actions', () => { page.getByLabel('block-item-CollectionField-users-form-users.username-Username').getByRole('textbox'), ).toHaveValue(''); }); - - test('customize: save record', async ({ page, mockPage }) => { - await mockPage(oneEmptyForm).goto(); - - await page.getByLabel('schema-initializer-ActionBar-createForm:configureActions-general').hover(); - await page.getByRole('menuitem', { name: 'Customize' }).hover(); - await page.getByRole('menuitem', { name: 'Save record' }).click(); - - await expect(page.getByRole('button', { name: 'Save record' })).toBeVisible(); - }); }); diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/schemaSettings.test.ts b/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/schemaSettings.test.ts index b9a54148d3..f60de08bde 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/schemaSettings.test.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/schemaSettings.test.ts @@ -402,16 +402,16 @@ test.describe('actions schema settings', () => { await mockPage(oneFormAndOneTableWithUsers).goto(); const openPopup = async () => { - if (!(await page.getByLabel('action-Action-Save record-').isVisible())) { + if (!(await page.getByLabel('action-Action-Submit-').isVisible())) { await page.getByLabel('schema-initializer-ActionBar-createForm:configureActions-users').hover(); - await page.getByRole('menuitem', { name: 'Customize right' }).hover(); - await page.getByRole('menuitem', { name: 'Save record' }).click(); + await page.getByRole('menuitem', { name: 'Submit' }).click(); } - await page.getByLabel('action-Action-Save record-').hover(); - await page.getByLabel('designer-schema-settings-Action-actionSettings:saveRecord-users').hover(); + await page.getByLabel('action-Action-Submit-').hover(); + await page.getByLabel('designer-schema-settings-Action-actionSettings:createSubmit-users').hover(); await page.getByRole('menuitem', { name: 'Assign field values' }).click(); + await page.waitForTimeout(500); if (!(await page.getByLabel('block-item-AssignedField-').getByRole('textbox').isVisible())) { await page.getByLabel('schema-initializer-Grid-assignFieldValuesForm:configureFields-users').hover(); await page.getByRole('menuitem', { name: 'Nickname' }).click(); @@ -419,8 +419,7 @@ test.describe('actions schema settings', () => { }; const expectNewValue = async (value: string) => { - await page.getByLabel('action-Action-Save record-').click(); - await page.getByRole('button', { name: 'OK', exact: true }).click(); + await page.getByLabel('action-Action-Submit-').click(); await page.getByLabel('action-Action-Refresh-refresh').click(); await expect(page.getByLabel('block-item-CardItem-users-table').getByText(value)).toBeVisible(); }; @@ -431,9 +430,9 @@ test.describe('actions schema settings', () => { // 2. 将 Nickname 字段的值设置为 `123456` await page.getByLabel('block-item-AssignedField-').getByRole('textbox').click(); await page.getByLabel('block-item-AssignedField-').getByRole('textbox').fill('123456'); - await page.getByRole('button', { name: 'Submit' }).click(); + await page.getByRole('button', { name: 'Submit', exact: true }).click(); - // 3. 保存后点击 Save record 按钮,然后刷新表格,应该显示一条 Nickname 为 “123456” 的记录 + // 3. 保存后点击 Submit 按钮,然后刷新表格,应该显示一条 Nickname 为 “123456” 的记录 await expectNewValue('123456'); // 4. 再次打开 Assign field values 配置弹窗,这次为 Nickname 设置一个变量值(Current role) @@ -447,9 +446,9 @@ test.describe('actions schema settings', () => { 'Current form', ]); await page.getByRole('menuitemcheckbox', { name: 'Current role' }).click(); - await page.getByRole('button', { name: 'Submit' }).click(); + await page.getByRole('button', { name: 'Submit', exact: true }).click(); - // 5. 保存后点击 Save record 按钮,然后刷新表格,应该显示一条 Nickname 为 “root” 的记录 + // 5. 保存后点击 Submit 按钮,然后刷新表格,应该显示一条 Nickname 为 “root” 的记录 await expectNewValue('root'); }); }); diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/schemaSettings1.test.ts b/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/schemaSettings1.test.ts index b8f7e98cf2..e418a4801d 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/schemaSettings1.test.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/form/__e2e__/form-create/schemaSettings1.test.ts @@ -741,6 +741,7 @@ test.describe('creation form block schema settings', () => { await page.getByLabel('action-Action-Add new-create-users-table').click(); await page.getByLabel('schema-initializer-Grid-popup:addNew:addBlock-users').hover(); await page.getByRole('menuitem', { name: 'form Form' }).first().hover(); + await page.getByRole('menuitem', { name: 'Current collection' }).hover(); await page.getByRole('menuitem', { name: 'Reference template' }).hover(); await page.getByRole('menuitem', { name: 'Users_Form (Fields only)' }).first().click(); await page.mouse.move(300, 0); diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/createCreateFormBlockUISchema.ts b/packages/core/client/src/modules/blocks/data-blocks/form/createCreateFormBlockUISchema.ts index 79b46cd93e..26b3df7887 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/createCreateFormBlockUISchema.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/form/createCreateFormBlockUISchema.ts @@ -16,6 +16,7 @@ export interface CreateFormBlockUISchemaOptions { collectionName?: string; association?: string; templateSchema?: ISchema; + /** 表示是通过 Other collections 选项创建的区块(由于历史遗留问题,这里的命名暂不做更改) */ isCusomeizeCreate?: boolean; } diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/createFormActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/createFormActionInitializers.tsx index e1445d2d3c..1cc415fa80 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/createFormActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/form/createFormActionInitializers.tsx @@ -9,97 +9,39 @@ import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer'; +const commonOptions = { + title: '{{t("Configure actions")}}', + icon: 'SettingOutlined', + items: [ + { + name: 'submit', + title: '{{t("Submit")}}', + Component: 'CreateSubmitActionInitializer', + schema: { + 'x-action-settings': {}, + }, + }, + { + name: 'customRequest', + title: '{{t("Custom request")}}', + Component: 'CustomRequestInitializer', + }, + ], +}; + /** * @deprecated * use `createFormActionInitializers` instead */ export const createFormActionInitializers_deprecated = new CompatibleSchemaInitializer({ name: 'CreateFormActionInitializers', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - items: [ - { - type: 'itemGroup', - title: '{{t("Enable actions")}}', - name: 'enableActions', - children: [ - { - name: 'submit', - title: '{{t("Submit")}}', - Component: 'CreateSubmitActionInitializer', - schema: { - 'x-action-settings': {}, - }, - }, - ], - }, - { - name: 'divider', - type: 'divider', - }, - { - type: 'subMenu', - title: '{{t("Customize")}}', - name: 'customize', - children: [ - { - name: 'saveRecord', - title: '{{t("Save record")}}', - Component: 'SaveRecordActionInitializer', - }, - { - name: 'customRequest', - title: '{{t("Custom request")}}', - Component: 'CustomRequestInitializer', - }, - ], - }, - ], + ...commonOptions, }); export const createFormActionInitializers = new CompatibleSchemaInitializer( { name: 'createForm:configureActions', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - items: [ - { - type: 'itemGroup', - title: '{{t("Enable actions")}}', - name: 'enableActions', - children: [ - { - name: 'submit', - title: '{{t("Submit")}}', - Component: 'CreateSubmitActionInitializer', - schema: { - 'x-action-settings': {}, - }, - }, - ], - }, - { - name: 'divider', - type: 'divider', - }, - { - type: 'subMenu', - title: '{{t("Customize")}}', - name: 'customize', - children: [ - { - name: 'saveRecord', - title: '{{t("Save record")}}', - Component: 'SaveRecordActionInitializer', - }, - { - name: 'customRequest', - title: '{{t("Custom request")}}', - Component: 'CustomRequestInitializer', - }, - ], - }, - ], + ...commonOptions, }, createFormActionInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/formActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/formActionInitializers.tsx index e01bba54af..0fa17d5dc9 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/formActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/form/formActionInitializers.tsx @@ -19,40 +19,17 @@ export const formActionInitializers = new SchemaInitializer({ icon: 'SettingOutlined', items: [ { - type: 'itemGroup', - name: 'enableActions', - title: '{{t("Enable actions")}}', - children: [ - { - name: 'submit', - title: '{{t("Submit")}}', - Component: 'CreateSubmitActionInitializer', - schema: { - 'x-action-settings': {}, - }, - }, - ], + name: 'submit', + title: '{{t("Submit")}}', + Component: 'CreateSubmitActionInitializer', + schema: { + 'x-action-settings': {}, + }, }, { - name: 'divider', - type: 'divider', - }, - { - name: 'customize', - type: 'subMenu', - title: '{{t("Customize")}}', - children: [ - { - name: 'saveRecord', - title: '{{t("Save record")}}', - Component: 'SaveRecordActionInitializer', - }, - { - name: 'customRequest', - title: '{{t("Custom request")}}', - Component: 'CustomRequestInitializer', - }, - ], + name: 'customRequest', + title: '{{t("Custom request")}}', + Component: 'CustomRequestInitializer', }, ], }); diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/formItemInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/formItemInitializers.tsx index f37f5c7ebd..bd0913b1c1 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/formItemInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/form/formItemInitializers.tsx @@ -11,13 +11,7 @@ import { CompatibleSchemaInitializer } from '../../../../application/schema-init import { AssociatedFields, ParentCollectionFields } from '../../../../schema-initializer/buttons/FormItemInitializers'; import { gridRowColWrap, useFormItemInitializerFields } from '../../../../schema-initializer/utils'; -/** - * @deprecated - * use `formItemInitializers` instead - * 表单里配置字段 - */ -export const formItemInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'FormItemInitializers', +const commonOptions = { wrap: gridRowColWrap, icon: 'SettingOutlined', title: '{{t("Configure fields")}}', @@ -46,39 +40,22 @@ export const formItemInitializers_deprecated = new CompatibleSchemaInitializer({ Component: 'MarkdownFormItemInitializer', }, ], +}; + +/** + * @deprecated + * use `formItemInitializers` instead + * 表单里配置字段 + */ +export const formItemInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'FormItemInitializers', + ...commonOptions, }); export const formItemInitializers = new CompatibleSchemaInitializer( { name: 'form:configureFields', - wrap: gridRowColWrap, - icon: 'SettingOutlined', - title: '{{t("Configure fields")}}', - items: [ - { - type: 'itemGroup', - name: 'displayFields', - title: '{{t("Display fields")}}', - useChildren: useFormItemInitializerFields, - }, - { - name: 'parentCollectionFields', - Component: ParentCollectionFields, - }, - { - name: 'associationFields', - Component: AssociatedFields, - }, - { - name: 'divider', - type: 'divider', - }, - { - name: 'addText', - title: '{{t("Add text")}}', - Component: 'MarkdownFormItemInitializer', - }, - ], + ...commonOptions, }, formItemInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/hooks/useCreateFormBlockDecoratorProps.ts b/packages/core/client/src/modules/blocks/data-blocks/form/hooks/useCreateFormBlockDecoratorProps.ts index 9a386b7d25..2cb11c15cf 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/hooks/useCreateFormBlockDecoratorProps.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/form/hooks/useCreateFormBlockDecoratorProps.ts @@ -8,10 +8,13 @@ */ import { useParentRecordCommon } from '../../../useParentRecordCommon'; +import { useHiddenForInherit } from './useHiddenForInherit'; export function useCreateFormBlockDecoratorProps(props) { let parentRecord; + const { hidden } = useHiddenForInherit(props); + // association 的值是固定不变的,所以这里可以使用 hooks if (props.association) { // eslint-disable-next-line react-hooks/rules-of-hooks @@ -20,5 +23,6 @@ export function useCreateFormBlockDecoratorProps(props) { return { parentRecord, + hidden, }; } diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/hooks/useEditFormBlockDecoratorProps.ts b/packages/core/client/src/modules/blocks/data-blocks/form/hooks/useEditFormBlockDecoratorProps.ts index fc1c2ac297..5eeb123e45 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/hooks/useEditFormBlockDecoratorProps.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/form/hooks/useEditFormBlockDecoratorProps.ts @@ -9,11 +9,14 @@ import { useParamsFromRecord } from '../../../../../block-provider/BlockProvider'; import { useDetailsParentRecord } from '../../details-single/hooks/useDetailsDecoratorProps'; +import { useHiddenForInherit } from './useHiddenForInherit'; export function useEditFormBlockDecoratorProps(props) { const params = useFormBlockParams(); let parentRecord; + const { hidden } = useHiddenForInherit(props); + // association 的值是固定不变的,所以这里可以使用 hooks if (props.association) { // 复用详情区块的 sourceId 获取逻辑 @@ -24,6 +27,7 @@ export function useEditFormBlockDecoratorProps(props) { return { params, parentRecord, + hidden, }; } diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/hooks/useHiddenForInherit.ts b/packages/core/client/src/modules/blocks/data-blocks/form/hooks/useHiddenForInherit.ts new file mode 100644 index 0000000000..f8d9bb4822 --- /dev/null +++ b/packages/core/client/src/modules/blocks/data-blocks/form/hooks/useHiddenForInherit.ts @@ -0,0 +1,48 @@ +/** + * 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 { useIsDetailBlock } from '../../../../../block-provider/FormBlockProvider'; +import { useCollection } from '../../../../../data-source/collection/CollectionProvider'; +import { useRecord } from '../../../../../record-provider'; +import { useDesignable } from '../../../../../schema-component/hooks/useDesignable'; + +/** + * 用于在继承表的场景下,隐藏区块。 + * 具体文档:https://nocobase.feishu.cn/docx/A3L9dNZhnoMBjRxVciBcFzwLnae + */ +export const useHiddenForInherit = (props) => { + const record = useRecord(); + const { collection, isCusomeizeCreate, hidden } = props; + const { __collection } = record; + const currentCollection = useCollection(); + const { designable } = useDesignable(); + const isDetailBlock = useIsDetailBlock(); + + if (!currentCollection) { + return { + hidden: hidden || false, + }; + } + + let detailFlag = false; + if (isDetailBlock) { + detailFlag = true; + if (!designable && __collection) { + detailFlag = __collection === collection; + } + } + const createFlag = + (currentCollection.name === (collection?.name || collection) && !isDetailBlock) || + !currentCollection.name || + !collection; + + return { + hidden: hidden || (!detailFlag && !createFlag && !isCusomeizeCreate), + }; +}; diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/index.ts b/packages/core/client/src/modules/blocks/data-blocks/form/index.ts index c9a1202129..df81fd7142 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/index.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/form/index.ts @@ -7,7 +7,6 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -export * from './CreateFormBlockInitializer'; export * from './FormBlockInitializer'; export * from './FormItemSchemaToolbar'; export * from './RecordFormBlockInitializer'; diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/updateFormActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/updateFormActionInitializers.tsx index 3020f820ae..cf5a10fc7c 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/updateFormActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/form/updateFormActionInitializers.tsx @@ -9,119 +9,50 @@ import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer'; +const commonOptions = { + title: '{{t("Configure actions")}}', + icon: 'SettingOutlined', + items: [ + { + name: 'submit', + title: '{{t("Submit")}}', + Component: 'UpdateSubmitActionInitializer', + schema: { + 'x-action-settings': {}, + }, + }, + { + name: 'popup', + title: '{{t("Popup")}}', + Component: 'PopupActionInitializer', + useComponentProps() { + return { + 'x-component': 'Action', + }; + }, + }, + { + type: 'item', + name: 'customRequest', + title: '{{t("Custom request")}}', + Component: 'CustomRequestInitializer', + }, + ], +}; + /** * @deprecated * use `updateFormActionInitializers` instead */ export const updateFormActionInitializers_deprecated = new CompatibleSchemaInitializer({ name: 'UpdateFormActionInitializers', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - items: [ - { - type: 'itemGroup', - title: '{{t("Enable actions")}}', - name: 'enableActions', - children: [ - { - name: 'submit', - title: '{{t("Submit")}}', - Component: 'UpdateSubmitActionInitializer', - schema: { - 'x-action-settings': {}, - }, - }, - ], - }, - { - name: 'divider', - type: 'divider', - }, - { - type: 'subMenu', - title: '{{t("Customize")}}', - name: 'customize', - children: [ - { - name: 'popup', - title: '{{t("Popup")}}', - Component: 'PopupActionInitializer', - useComponentProps() { - return { - 'x-component': 'Action', - }; - }, - }, - { - name: 'saveRecord', - title: '{{t("Save record")}}', - Component: 'SaveRecordActionInitializer', - }, - { - type: 'item', - name: 'customRequest', - title: '{{t("Custom request")}}', - Component: 'CustomRequestInitializer', - }, - ], - }, - ], + ...commonOptions, }); export const updateFormActionInitializers = new CompatibleSchemaInitializer( { name: 'editForm:configureActions', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - items: [ - { - type: 'itemGroup', - title: '{{t("Enable actions")}}', - name: 'enableActions', - children: [ - { - name: 'submit', - title: '{{t("Submit")}}', - Component: 'UpdateSubmitActionInitializer', - schema: { - 'x-action-settings': {}, - }, - }, - ], - }, - { - name: 'divider', - type: 'divider', - }, - { - type: 'subMenu', - title: '{{t("Customize")}}', - name: 'customize', - children: [ - { - name: 'popup', - title: '{{t("Popup")}}', - Component: 'PopupActionInitializer', - useComponentProps() { - return { - 'x-component': 'Action', - }; - }, - }, - { - name: 'saveRecord', - title: '{{t("Save record")}}', - Component: 'SaveRecordActionInitializer', - }, - { - type: 'item', - name: 'customRequest', - title: '{{t("Custom request")}}', - Component: 'CustomRequestInitializer', - }, - ], - }, - ], + ...commonOptions, }, updateFormActionInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/blocks/data-blocks/grid-card/GridCardActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/grid-card/GridCardActionInitializers.tsx index 2c82134483..90d19b3451 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/grid-card/GridCardActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/grid-card/GridCardActionInitializers.tsx @@ -10,12 +10,7 @@ import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer'; import { useCollection_deprecated } from '../../../../collection-manager'; -/** - * @deprecated - * use `gridCardActionInitializers` instead - */ -export const gridCardActionInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'GridCardActionInitializers', +const commonOptions = { title: "{{t('Configure actions')}}", icon: 'SettingOutlined', style: { @@ -23,154 +18,82 @@ export const gridCardActionInitializers_deprecated = new CompatibleSchemaInitial }, items: [ { - type: 'itemGroup', - title: "{{t('Enable actions')}}", - name: 'enableActions', - children: [ - { - name: 'filter', - title: "{{t('Filter')}}", - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'left', - }, + name: 'filter', + title: "{{t('Filter')}}", + Component: 'FilterActionInitializer', + schema: { + 'x-align': 'left', + }, + }, + { + name: 'addNew', + title: "{{t('Add new')}}", + Component: 'CreateActionInitializer', + schema: { + 'x-align': 'right', + 'x-decorator': 'ACLActionProvider', + 'x-acl-action-props': { + skipScopeCheck: true, }, - { - name: 'addNew', - title: "{{t('Add new')}}", - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'file', 'sql'].includes(collection.template) || collection?.writableView; - }, + }, + useVisible() { + const collection = useCollection_deprecated(); + return !['view', 'file', 'sql'].includes(collection.template) || collection?.writableView; + }, + }, + { + name: 'refresh', + title: "{{t('Refresh')}}", + Component: 'RefreshActionInitializer', + schema: { + 'x-align': 'right', + }, + }, + { + name: 'import', + title: "{{t('Import')}}", + Component: 'ImportActionInitializer', + schema: { + 'x-align': 'right', + 'x-acl-action': 'importXlsx', + 'x-decorator': 'ACLActionProvider', + 'x-acl-action-props': { + skipScopeCheck: true, }, - { - name: 'refresh', - title: "{{t('Refresh')}}", - Component: 'RefreshActionInitializer', - schema: { - 'x-align': 'right', - }, + }, + useVisible() { + const collection = useCollection_deprecated(); + return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; + }, + }, + { + name: 'export', + title: "{{t('Export')}}", + Component: 'ExportActionInitializer', + schema: { + 'x-align': 'right', + 'x-decorator': 'ACLActionProvider', + 'x-acl-action-props': { + skipScopeCheck: true, }, - { - name: 'import', - title: "{{t('Import')}}", - Component: 'ImportActionInitializer', - schema: { - 'x-align': 'right', - 'x-acl-action': 'importXlsx', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - name: 'export', - title: "{{t('Export')}}", - Component: 'ExportActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - }, - ], + }, }, ], +}; + +/** + * @deprecated + * use `gridCardActionInitializers` instead + */ +export const gridCardActionInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'GridCardActionInitializers', + ...commonOptions, }); export const gridCardActionInitializers = new CompatibleSchemaInitializer( { name: 'gridCard:configureActions', - title: "{{t('Configure actions')}}", - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'itemGroup', - title: "{{t('Enable actions')}}", - name: 'enableActions', - children: [ - { - name: 'filter', - title: "{{t('Filter')}}", - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'left', - }, - }, - { - name: 'addNew', - title: "{{t('Add new')}}", - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'file', 'sql'].includes(collection.template) || collection?.writableView; - }, - }, - { - name: 'refresh', - title: "{{t('Refresh')}}", - Component: 'RefreshActionInitializer', - schema: { - 'x-align': 'right', - }, - }, - { - name: 'import', - title: "{{t('Import')}}", - Component: 'ImportActionInitializer', - schema: { - 'x-align': 'right', - 'x-acl-action': 'importXlsx', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - name: 'export', - title: "{{t('Export')}}", - Component: 'ExportActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - }, - ], - }, - ], + ...commonOptions, }, gridCardActionInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/blocks/data-blocks/grid-card/__e2e__/schemaInitializer.test.ts b/packages/core/client/src/modules/blocks/data-blocks/grid-card/__e2e__/schemaInitializer.test.ts index 55f7fb1839..ba92d21f74 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/grid-card/__e2e__/schemaInitializer.test.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/grid-card/__e2e__/schemaInitializer.test.ts @@ -7,10 +7,17 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { createBlockInPage, expect, oneEmptyGridCardBlock, test } from '@nocobase/test/e2e'; +import { Page, createBlockInPage, expect, oneEmptyGridCardBlock, test } from '@nocobase/test/e2e'; import { oneEmptyTableWithUsers } from '../../details-multi/__e2e__/templatesOfBug'; import { oneGridCardWithInheritFields } from './templatesOfBug'; +const deleteButton = async (page: Page, name: string) => { + await page.getByRole('button', { name }).hover(); + await page.getByRole('button', { name }).getByLabel('designer-schema-settings-').hover(); + await page.getByRole('menuitem', { name: 'Delete' }).click(); + await page.getByRole('button', { name: 'OK', exact: true }).click(); +}; + test.describe('where grid card block can be added', () => { test('page', async ({ page, mockPage }) => { await mockPage().goto(); @@ -63,24 +70,15 @@ test.describe('configure global actions', () => { await page.getByRole('menuitem', { name: 'Add new' }).click(); await page.getByRole('menuitem', { name: 'Refresh' }).click(); - await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).toBeChecked(); - await page.mouse.move(300, 0); await expect(page.getByRole('button', { name: 'Filter' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Add new' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Refresh' })).toBeVisible(); // delete buttons - await page.getByLabel('schema-initializer-ActionBar-gridCard:configureActions-general').hover(); - await page.getByRole('menuitem', { name: 'Filter' }).click(); - await page.getByRole('menuitem', { name: 'Add new' }).click(); - await page.getByRole('menuitem', { name: 'Refresh' }).click(); - - await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).not.toBeChecked(); + await deleteButton(page, 'Filter'); + await deleteButton(page, 'Add new'); + await deleteButton(page, 'Refresh'); await page.mouse.move(300, 0); await expect(page.getByRole('button', { name: 'Filter' })).not.toBeVisible(); @@ -100,24 +98,15 @@ test.describe('configure item actions', () => { await page.getByRole('menuitem', { name: 'Edit' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click(); - await expect(page.getByRole('menuitem', { name: 'View' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).toBeChecked(); - await page.mouse.move(300, 0); await expect(page.getByLabel('action-Action.Link-View-view-general-grid-card').first()).toBeVisible(); await expect(page.getByLabel('action-Action.Link-Edit-update-general-grid-card').first()).toBeVisible(); await expect(page.getByLabel('action-Action.Link-Delete-destroy-general-grid-card').first()).toBeVisible(); // delete buttons - await page.getByLabel('schema-initializer-ActionBar-gridCard:configureItemActions-general').first().hover(); - await page.getByRole('menuitem', { name: 'View' }).click(); - await page.getByRole('menuitem', { name: 'Edit' }).click(); - await page.getByRole('menuitem', { name: 'Delete' }).click(); - - await expect(page.getByRole('menuitem', { name: 'View' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).not.toBeChecked(); + await deleteButton(page, 'View'); + await deleteButton(page, 'Edit'); + await deleteButton(page, 'Delete'); await page.mouse.move(300, 0); await expect(page.getByLabel('action-Action.Link-View-view-general-grid-card').first()).not.toBeVisible(); @@ -131,7 +120,6 @@ test.describe('configure item actions', () => { await nocoPage.goto(); await page.getByLabel('schema-initializer-ActionBar-gridCard:configureItemActions-general').first().hover(); - await page.getByRole('menuitem', { name: 'Customize' }).hover(); await page.getByRole('menuitem', { name: 'Popup' }).click(); await page.getByRole('menuitem', { name: 'Update record' }).click(); diff --git a/packages/core/client/src/modules/blocks/data-blocks/grid-card/gridCardItemActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/grid-card/gridCardItemActionInitializers.tsx index 3fee3def3a..0b87e186f7 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/grid-card/gridCardItemActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/grid-card/gridCardItemActionInitializers.tsx @@ -10,205 +10,98 @@ import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer'; import { useCollection_deprecated } from '../../../../collection-manager'; +const commonOptions = { + title: '{{t("Configure actions")}}', + icon: 'SettingOutlined', + items: [ + { + name: 'view', + title: '{{t("View")}}', + Component: 'ViewActionInitializer', + schema: { + 'x-component': 'Action.Link', + 'x-action': 'view', + 'x-decorator': 'ACLActionProvider', + 'x-align': 'left', + }, + }, + { + name: 'edit', + title: '{{t("Edit")}}', + Component: 'UpdateActionInitializer', + schema: { + 'x-component': 'Action.Link', + 'x-action': 'update', + 'x-decorator': 'ACLActionProvider', + 'x-align': 'left', + }, + useVisible() { + const collection = useCollection_deprecated(); + return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; + }, + }, + { + name: 'delete', + title: '{{t("Delete")}}', + Component: 'DestroyActionInitializer', + schema: { + 'x-component': 'Action.Link', + 'x-action': 'destroy', + 'x-decorator': 'ACLActionProvider', + 'x-align': 'left', + }, + useVisible() { + const collection = useCollection_deprecated(); + return collection.template !== 'sql'; + }, + }, + { + name: 'popup', + title: '{{t("Popup")}}', + Component: 'PopupActionInitializer', + useComponentProps() { + return { + 'x-component': 'Action.Link', + }; + }, + }, + { + name: 'update-record', + title: '{{t("Update record")}}', + Component: 'UpdateRecordActionInitializer', + useVisible() { + const collection = useCollection_deprecated(); + return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; + }, + }, + { + name: 'customRequest', + title: '{{t("Custom request")}}', + Component: 'CustomRequestInitializer', + schema: { + 'x-action': 'customize:table:request', + }, + useVisible() { + const collection = useCollection_deprecated(); + return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; + }, + }, + ], +}; + /** * @deprecated * use `gridCardItemActionInitializers` instead */ export const gridCardItemActionInitializers_deprecated = new CompatibleSchemaInitializer({ name: 'GridCardItemActionInitializers', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - items: [ - { - type: 'itemGroup', - title: '{{t("Enable actions")}}', - name: 'enable-actions', - children: [ - { - name: 'view', - title: '{{t("View")}}', - Component: 'ViewActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'view', - 'x-decorator': 'ACLActionProvider', - 'x-align': 'left', - }, - }, - { - name: 'edit', - title: '{{t("Edit")}}', - Component: 'UpdateActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'update', - 'x-decorator': 'ACLActionProvider', - 'x-align': 'left', - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - name: 'delete', - title: '{{t("Delete")}}', - Component: 'DestroyActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'destroy', - 'x-decorator': 'ACLActionProvider', - 'x-align': 'left', - }, - useVisible() { - const collection = useCollection_deprecated(); - return collection.template !== 'sql'; - }, - }, - ], - }, - { - name: 'divider', - type: 'divider', - }, - { - type: 'subMenu', - title: '{{t("Customize")}}', - name: 'customize', - children: [ - { - name: 'popup', - title: '{{t("Popup")}}', - Component: 'PopupActionInitializer', - useComponentProps() { - return { - 'x-component': 'Action.Link', - }; - }, - }, - { - name: 'update-record', - title: '{{t("Update record")}}', - Component: 'UpdateRecordActionInitializer', - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - name: 'customRequest', - title: '{{t("Custom request")}}', - Component: 'CustomRequestInitializer', - schema: { - 'x-action': 'customize:table:request', - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - ], - }, - ], + ...commonOptions, }); export const gridCardItemActionInitializers = new CompatibleSchemaInitializer( { name: 'gridCard:configureItemActions', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - items: [ - { - type: 'itemGroup', - title: '{{t("Enable actions")}}', - name: 'enable-actions', - children: [ - { - name: 'view', - title: '{{t("View")}}', - Component: 'ViewActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'view', - 'x-decorator': 'ACLActionProvider', - 'x-align': 'left', - }, - }, - { - name: 'edit', - title: '{{t("Edit")}}', - Component: 'UpdateActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'update', - 'x-decorator': 'ACLActionProvider', - 'x-align': 'left', - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - name: 'delete', - title: '{{t("Delete")}}', - Component: 'DestroyActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'destroy', - 'x-decorator': 'ACLActionProvider', - 'x-align': 'left', - }, - useVisible() { - const collection = useCollection_deprecated(); - return collection.template !== 'sql'; - }, - }, - ], - }, - { - name: 'divider', - type: 'divider', - }, - { - type: 'subMenu', - title: '{{t("Customize")}}', - name: 'customize', - children: [ - { - name: 'popup', - title: '{{t("Popup")}}', - Component: 'PopupActionInitializer', - useComponentProps() { - return { - 'x-component': 'Action.Link', - }; - }, - }, - { - name: 'update-record', - title: '{{t("Update record")}}', - Component: 'UpdateRecordActionInitializer', - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - name: 'customRequest', - title: '{{t("Custom request")}}', - Component: 'CustomRequestInitializer', - schema: { - 'x-action': 'customize:table:request', - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - ], - }, - ], + ...commonOptions, }, gridCardItemActionInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/blocks/data-blocks/list/ListActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/list/ListActionInitializers.tsx index 6e6891a9d5..cc1226b9c1 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/list/ListActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/list/ListActionInitializers.tsx @@ -10,13 +10,7 @@ import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer'; import { useCollection_deprecated } from '../../../../collection-manager'; -/** - * @deprecated - * use `listActionInitializers` instead - * 表单的操作配置 - */ -export const listActionInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'ListActionInitializers', +const commonOptions = { title: "{{t('Configure actions')}}", icon: 'SettingOutlined', style: { @@ -24,162 +18,87 @@ export const listActionInitializers_deprecated = new CompatibleSchemaInitializer }, items: [ { - type: 'itemGroup', - name: 'enableActions', - title: "{{t('Enable actions')}}", - children: [ - { - name: 'filter', - title: "{{t('Filter')}}", - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'left', - }, + name: 'filter', + title: "{{t('Filter')}}", + Component: 'FilterActionInitializer', + schema: { + 'x-align': 'left', + }, + }, + { + name: 'addNew', + title: "{{t('Add new')}}", + Component: 'CreateActionInitializer', + schema: { + 'x-align': 'right', + 'x-decorator': 'ACLActionProvider', + 'x-acl-action-props': { + skipScopeCheck: true, }, - { - name: 'addNew', - title: "{{t('Add new')}}", - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return ( - (collection.template !== 'view' || collection?.writableView) && - collection.template !== 'file' && - collection.template !== 'sql' - ); - }, + }, + useVisible() { + const collection = useCollection_deprecated(); + return ( + (collection.template !== 'view' || collection?.writableView) && + collection.template !== 'file' && + collection.template !== 'sql' + ); + }, + }, + { + name: 'refresh', + title: "{{t('Refresh')}}", + Component: 'RefreshActionInitializer', + schema: { + 'x-align': 'right', + }, + }, + { + name: 'import', + title: "{{t('Import')}}", + Component: 'ImportActionInitializer', + schema: { + 'x-align': 'right', + 'x-acl-action': 'importXlsx', + 'x-decorator': 'ACLActionProvider', + 'x-acl-action-props': { + skipScopeCheck: true, }, - { - name: 'refresh', - title: "{{t('Refresh')}}", - Component: 'RefreshActionInitializer', - schema: { - 'x-align': 'right', - }, + }, + useVisible() { + const collection = useCollection_deprecated(); + return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; + }, + }, + { + name: 'export', + title: "{{t('Export')}}", + Component: 'ExportActionInitializer', + schema: { + 'x-align': 'right', + 'x-decorator': 'ACLActionProvider', + 'x-acl-action-props': { + skipScopeCheck: true, }, - { - name: 'import', - title: "{{t('Import')}}", - Component: 'ImportActionInitializer', - schema: { - 'x-align': 'right', - 'x-acl-action': 'importXlsx', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - name: 'export', - title: "{{t('Export')}}", - Component: 'ExportActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - }, - ], + }, }, ], +}; + +/** + * @deprecated + * use `listActionInitializers` instead + * 表单的操作配置 + */ +export const listActionInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'ListActionInitializers', + ...commonOptions, }); export const listActionInitializers = new CompatibleSchemaInitializer( { name: 'list:configureActions', - title: "{{t('Configure actions')}}", - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'itemGroup', - name: 'enableActions', - title: "{{t('Enable actions')}}", - children: [ - { - name: 'filter', - title: "{{t('Filter')}}", - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'left', - }, - }, - { - name: 'addNew', - title: "{{t('Add new')}}", - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return ( - (collection.template !== 'view' || collection?.writableView) && - collection.template !== 'file' && - collection.template !== 'sql' - ); - }, - }, - { - name: 'refresh', - title: "{{t('Refresh')}}", - Component: 'RefreshActionInitializer', - schema: { - 'x-align': 'right', - }, - }, - { - name: 'import', - title: "{{t('Import')}}", - Component: 'ImportActionInitializer', - schema: { - 'x-align': 'right', - 'x-acl-action': 'importXlsx', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - name: 'export', - title: "{{t('Export')}}", - Component: 'ExportActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - }, - ], - }, - ], + ...commonOptions, }, listActionInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/blocks/data-blocks/list/__e2e__/schemaInitializer.test.ts b/packages/core/client/src/modules/blocks/data-blocks/list/__e2e__/schemaInitializer.test.ts index 53917f708f..10bf64fe4a 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/list/__e2e__/schemaInitializer.test.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/list/__e2e__/schemaInitializer.test.ts @@ -7,9 +7,16 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { createBlockInPage, expect, oneEmptyListBlock, test } from '@nocobase/test/e2e'; +import { Page, createBlockInPage, expect, oneEmptyListBlock, test } from '@nocobase/test/e2e'; import { oneEmptyTableWithUsers } from '../../details-multi/__e2e__/templatesOfBug'; +const deleteButton = async (page: Page, name: string) => { + await page.getByRole('button', { name }).hover(); + await page.getByRole('button', { name }).getByLabel('designer-schema-settings-').hover(); + await page.getByRole('menuitem', { name: 'Delete' }).click(); + await page.getByRole('button', { name: 'OK', exact: true }).click(); +}; + test.describe('where list block can be added', () => { test('page', async ({ page, mockPage }) => { await mockPage().goto(); @@ -60,24 +67,15 @@ test.describe('configure global actions', () => { await page.getByRole('menuitem', { name: 'Add new' }).click(); await page.getByRole('menuitem', { name: 'Refresh' }).click(); - await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).toBeChecked(); - await page.mouse.move(300, 0); await expect(page.getByRole('button', { name: 'Filter' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Add new' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Refresh' })).toBeVisible(); // delete buttons - await page.getByLabel('schema-initializer-ActionBar-list:configureActions-general').hover(); - await page.getByRole('menuitem', { name: 'Filter' }).click(); - await page.getByRole('menuitem', { name: 'Add new' }).click(); - await page.getByRole('menuitem', { name: 'Refresh' }).click(); - - await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).not.toBeChecked(); + await deleteButton(page, 'Filter'); + await deleteButton(page, 'Add new'); + await deleteButton(page, 'Refresh'); await page.mouse.move(300, 0); await expect(page.getByRole('button', { name: 'Filter' })).not.toBeVisible(); @@ -97,24 +95,15 @@ test.describe('configure item actions', () => { await page.getByRole('menuitem', { name: 'Edit' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click(); - await expect(page.getByRole('menuitem', { name: 'View' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).toBeChecked(); - await page.mouse.move(300, 0); await expect(page.getByLabel('action-Action.Link-View-view-general-list').first()).toBeVisible(); await expect(page.getByLabel('action-Action.Link-Edit-update-general-list').first()).toBeVisible(); await expect(page.getByLabel('action-Action.Link-Delete-destroy-general-list').first()).toBeVisible(); // delete buttons - await page.getByLabel('schema-initializer-ActionBar-list:configureItemActions-general').first().hover(); - await page.getByRole('menuitem', { name: 'View' }).click(); - await page.getByRole('menuitem', { name: 'Edit' }).click(); - await page.getByRole('menuitem', { name: 'Delete' }).click(); - - await expect(page.getByRole('menuitem', { name: 'View' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).not.toBeChecked(); + await deleteButton(page, 'View'); + await deleteButton(page, 'Edit'); + await deleteButton(page, 'Delete'); await page.mouse.move(300, 0); await expect(page.getByLabel('action-Action.Link-View-view-general-list').first()).not.toBeVisible(); @@ -128,7 +117,6 @@ test.describe('configure item actions', () => { await nocoPage.goto(); await page.getByLabel('schema-initializer-ActionBar-list:configureItemActions-general').first().hover(); - await page.getByRole('menuitem', { name: 'Customize' }).hover(); await page.getByRole('menuitem', { name: 'Popup' }).click(); await page.getByRole('menuitem', { name: 'Update record' }).click(); diff --git a/packages/core/client/src/modules/blocks/data-blocks/list/listItemActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/list/listItemActionInitializers.tsx index 54c43df806..9bab668078 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/list/listItemActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/list/listItemActionInitializers.tsx @@ -10,205 +10,98 @@ import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer'; import { useCollection_deprecated } from '../../../../collection-manager'; +const commonOptions = { + title: '{{t("Configure actions")}}', + icon: 'SettingOutlined', + items: [ + { + name: 'view', + title: '{{t("View")}}', + Component: 'ViewActionInitializer', + schema: { + 'x-component': 'Action.Link', + 'x-action': 'view', + 'x-decorator': 'ACLActionProvider', + 'x-align': 'left', + }, + }, + { + name: 'edit', + title: '{{t("Edit")}}', + Component: 'UpdateActionInitializer', + schema: { + 'x-component': 'Action.Link', + 'x-action': 'update', + 'x-decorator': 'ACLActionProvider', + 'x-align': 'left', + }, + useVisible() { + const collection = useCollection_deprecated(); + return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; + }, + }, + { + name: 'delete', + title: '{{t("Delete")}}', + Component: 'DestroyActionInitializer', + schema: { + 'x-component': 'Action.Link', + 'x-action': 'destroy', + 'x-decorator': 'ACLActionProvider', + 'x-align': 'left', + }, + useVisible() { + const collection = useCollection_deprecated(); + return collection.template !== 'sql'; + }, + }, + { + name: 'popup', + title: '{{t("Popup")}}', + Component: 'PopupActionInitializer', + useComponentProps() { + return { + 'x-component': 'Action.Link', + }; + }, + }, + { + name: 'updateRecord', + title: '{{t("Update record")}}', + Component: 'UpdateRecordActionInitializer', + useVisible() { + const collection = useCollection_deprecated(); + return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; + }, + }, + { + name: 'customRequest', + title: '{{t("Custom request")}}', + Component: 'CustomRequestInitializer', + schema: { + 'x-action': 'customize:table:request', + }, + useVisible() { + const collection = useCollection_deprecated(); + return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; + }, + }, + ], +}; + /** * @deprecated * use `listItemActionInitializers` instead */ export const listItemActionInitializers_deprecated = new CompatibleSchemaInitializer({ name: 'ListItemActionInitializers', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - items: [ - { - type: 'itemGroup', - name: 'enableActions', - title: '{{t("Enable actions")}}', - children: [ - { - name: 'view', - title: '{{t("View")}}', - Component: 'ViewActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'view', - 'x-decorator': 'ACLActionProvider', - 'x-align': 'left', - }, - }, - { - name: 'edit', - title: '{{t("Edit")}}', - Component: 'UpdateActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'update', - 'x-decorator': 'ACLActionProvider', - 'x-align': 'left', - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - name: 'delete', - title: '{{t("Delete")}}', - Component: 'DestroyActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'destroy', - 'x-decorator': 'ACLActionProvider', - 'x-align': 'left', - }, - useVisible() { - const collection = useCollection_deprecated(); - return collection.template !== 'sql'; - }, - }, - ], - }, - { - name: 'divider', - type: 'divider', - }, - { - type: 'subMenu', - title: '{{t("Customize")}}', - name: 'customize', - children: [ - { - name: 'popup', - title: '{{t("Popup")}}', - Component: 'PopupActionInitializer', - useComponentProps() { - return { - 'x-component': 'Action.Link', - }; - }, - }, - { - name: 'updateRecord', - title: '{{t("Update record")}}', - Component: 'UpdateRecordActionInitializer', - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - name: 'customRequest', - title: '{{t("Custom request")}}', - Component: 'CustomRequestInitializer', - schema: { - 'x-action': 'customize:table:request', - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - ], - }, - ], + ...commonOptions, }); export const listItemActionInitializers = new CompatibleSchemaInitializer( { name: 'list:configureItemActions', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - items: [ - { - type: 'itemGroup', - name: 'enableActions', - title: '{{t("Enable actions")}}', - children: [ - { - name: 'view', - title: '{{t("View")}}', - Component: 'ViewActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'view', - 'x-decorator': 'ACLActionProvider', - 'x-align': 'left', - }, - }, - { - name: 'edit', - title: '{{t("Edit")}}', - Component: 'UpdateActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'update', - 'x-decorator': 'ACLActionProvider', - 'x-align': 'left', - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - name: 'delete', - title: '{{t("Delete")}}', - Component: 'DestroyActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'destroy', - 'x-decorator': 'ACLActionProvider', - 'x-align': 'left', - }, - useVisible() { - const collection = useCollection_deprecated(); - return collection.template !== 'sql'; - }, - }, - ], - }, - { - name: 'divider', - type: 'divider', - }, - { - type: 'subMenu', - title: '{{t("Customize")}}', - name: 'customize', - children: [ - { - name: 'popup', - title: '{{t("Popup")}}', - Component: 'PopupActionInitializer', - useComponentProps() { - return { - 'x-component': 'Action.Link', - }; - }, - }, - { - name: 'updateRecord', - title: '{{t("Update record")}}', - Component: 'UpdateRecordActionInitializer', - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - name: 'customRequest', - title: '{{t("Custom request")}}', - Component: 'CustomRequestInitializer', - schema: { - 'x-action': 'customize:table:request', - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - ], - }, - ], + ...commonOptions, }, listItemActionInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/blocks/data-blocks/table-selector/__e2e__/schemaInitializer.test.ts b/packages/core/client/src/modules/blocks/data-blocks/table-selector/__e2e__/schemaInitializer.test.ts index 6360d5bfb8..15637654ab 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/table-selector/__e2e__/schemaInitializer.test.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/table-selector/__e2e__/schemaInitializer.test.ts @@ -10,6 +10,13 @@ import { Page, expect, test } from '@nocobase/test/e2e'; import { createTable } from './utils'; +const deleteButton = async (page: Page, name: string) => { + await page.getByRole('button', { name }).hover(); + await page.getByRole('button', { name }).getByLabel('designer-schema-settings-').hover(); + await page.getByRole('menuitem', { name: 'Delete' }).click(); + await page.getByRole('button', { name: 'OK', exact: true }).click(); +}; + test.describe('where table data selector can be added', () => { test('popup', async ({ page, mockPage }) => { await createTable({ page, mockPage, fieldName: 'manyToOne' }); @@ -35,11 +42,6 @@ test.describe('configure actions', () => { await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Refresh' }).click(); - await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).toBeChecked(); - await page.mouse.move(300, 0); await expect(page.getByRole('button', { name: 'Filter' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Add new' })).toBeVisible(); @@ -47,16 +49,10 @@ test.describe('configure actions', () => { await expect(page.getByRole('button', { name: 'Refresh' })).toBeVisible(); // delete buttons - await page.getByLabel('schema-initializer-ActionBar-table:configureActions-users').hover(); - await page.getByRole('menuitem', { name: 'Filter' }).click(); - await page.getByRole('menuitem', { name: 'Add new' }).click(); - await page.getByRole('menuitem', { name: 'Delete' }).click(); - await page.getByRole('menuitem', { name: 'Refresh' }).click(); - - await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).not.toBeChecked(); + await deleteButton(page, 'Filter'); + await deleteButton(page, 'Add new'); + await deleteButton(page, 'Delete'); + await deleteButton(page, 'Refresh'); await page.mouse.move(300, 0); await expect(page.getByRole('button', { name: 'Filter' })).not.toBeVisible(); @@ -69,7 +65,6 @@ test.describe('configure actions', () => { await createTable({ page, mockPage, fieldName: 'manyToOne' }); await page.getByLabel('schema-initializer-ActionBar-table:configureActions-users').hover(); - await page.getByRole('menuitem', { name: 'Customize' }).hover(); await page.getByRole('menuitem', { name: 'Bulk update' }).click(); await page.mouse.move(300, 0); diff --git a/packages/core/client/src/modules/blocks/data-blocks/table/TableActionColumnInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/table/TableActionColumnInitializers.tsx index 32efe79b5b..039ff3d9bb 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/table/TableActionColumnInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/table/TableActionColumnInitializers.tsx @@ -8,7 +8,7 @@ */ import { MenuOutlined } from '@ant-design/icons'; -import { ISchema, useFieldSchema, useField } from '@formily/react'; +import { ISchema, useField, useFieldSchema } from '@formily/react'; import _ from 'lodash'; import React from 'react'; import { useTranslation } from 'react-i18next'; @@ -18,10 +18,10 @@ import { SchemaInitializerActionModal } from '../../../../application/schema-ini import { SchemaInitializerItem } from '../../../../application/schema-initializer/components/SchemaInitializerItem'; import { useSchemaInitializer } from '../../../../application/schema-initializer/context'; import { useCollection_deprecated } from '../../../../collection-manager'; +import { SelectWithTitle } from '../../../../common/SelectWithTitle'; import { useDataBlockProps } from '../../../../data-source'; import { createDesignable, useDesignable } from '../../../../schema-component'; import { useGetAriaLabelOfDesigner } from '../../../../schema-settings/hooks/useGetAriaLabelOfDesigner'; -import { SelectWithTitle } from '../../../../common/SelectWithTitle'; export const Resizable = () => { const { t } = useTranslation(); @@ -112,6 +112,7 @@ export const SchemaSettingsFixed = () => { ); }; + const commonOptions = { insertPosition: 'beforeEnd', useInsert: function useInsert() { @@ -154,145 +155,130 @@ const commonOptions = { }, items: [ { - type: 'itemGroup', - name: 'actions', - title: '{{t("Enable actions")}}', - children: [ - { - type: 'item', - title: '{{t("View")}}', - name: 'view', - Component: 'ViewActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'view', - 'x-decorator': 'ACLActionProvider', - }, - }, - { - type: 'item', - name: 'edit', - title: '{{t("Edit")}}', - Component: 'UpdateActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'update', - 'x-decorator': 'ACLActionProvider', - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - type: 'item', - title: '{{t("Delete")}}', - name: 'delete', - Component: 'DestroyActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'destroy', - 'x-decorator': 'ACLActionProvider', - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - type: 'item', - title: '{{t("Disassociate")}}', - name: 'disassociate', - Component: 'DisassociateActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'disassociate', - 'x-acl-action': 'destroy', - 'x-decorator': 'ACLActionProvider', - }, - useVisible() { - const props = useDataBlockProps(); - const collection = useCollection_deprecated(); - return ( - !!props?.association && - (collection.template !== 'view' || collection?.writableView) && - collection.template !== 'sql' - ); - }, - }, - { - type: 'item', - title: '{{t("Add child")}}', - name: 'addChildren', - Component: 'CreateChildInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'create', - 'x-decorator': 'ACLActionProvider', - }, - useVisible() { - const fieldSchema = useFieldSchema(); - const collection = useCollection_deprecated(); - const { treeTable } = fieldSchema?.parent?.parent['x-decorator-props'] || {}; - return collection.tree && treeTable; - }, - }, - ], + type: 'item', + title: '{{t("View")}}', + name: 'view', + Component: 'ViewActionInitializer', + schema: { + 'x-component': 'Action.Link', + 'x-action': 'view', + 'x-decorator': 'ACLActionProvider', + }, + }, + { + type: 'item', + name: 'edit', + title: '{{t("Edit")}}', + Component: 'UpdateActionInitializer', + schema: { + 'x-component': 'Action.Link', + 'x-action': 'update', + 'x-decorator': 'ACLActionProvider', + }, + useVisible() { + const collection = useCollection_deprecated(); + return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; + }, + }, + { + type: 'item', + title: '{{t("Delete")}}', + name: 'delete', + Component: 'DestroyActionInitializer', + schema: { + 'x-component': 'Action.Link', + 'x-action': 'destroy', + 'x-decorator': 'ACLActionProvider', + }, + useVisible() { + const collection = useCollection_deprecated(); + return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; + }, + }, + { + type: 'item', + title: '{{t("Disassociate")}}', + name: 'disassociate', + Component: 'DisassociateActionInitializer', + schema: { + 'x-component': 'Action.Link', + 'x-action': 'disassociate', + 'x-acl-action': 'destroy', + 'x-decorator': 'ACLActionProvider', + }, + useVisible() { + const props = useDataBlockProps(); + const collection = useCollection_deprecated(); + return ( + !!props?.association && + (collection.template !== 'view' || collection?.writableView) && + collection.template !== 'sql' + ); + }, + }, + { + type: 'item', + title: '{{t("Add child")}}', + name: 'addChildren', + Component: 'CreateChildInitializer', + schema: { + 'x-component': 'Action.Link', + 'x-action': 'create', + 'x-decorator': 'ACLActionProvider', + }, + useVisible() { + const fieldSchema = useFieldSchema(); + const collection = useCollection_deprecated(); + const { treeTable } = fieldSchema?.parent?.parent['x-decorator-props'] || {}; + return collection.tree && treeTable; + }, + }, + { + type: 'item', + title: '{{t("Popup")}}', + name: 'popup', + Component: 'PopupActionInitializer', + }, + { + type: 'item', + title: '{{t("Update record")}}', + name: 'updateRecord', + Component: 'UpdateRecordActionInitializer', + useVisible() { + const collection = useCollection_deprecated(); + return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; + }, + }, + { + name: 'customRequest', + title: '{{t("Custom request")}}', + Component: 'CustomRequestInitializer', + schema: { + 'x-action': 'customize:table:request', + }, + useVisible() { + const collection = useCollection_deprecated(); + return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; + }, }, { name: 'divider', type: 'divider', - }, - { - type: 'subMenu', - title: '{{t("Customize")}}', - name: 'customize', - children: [ - { - type: 'item', - title: '{{t("Popup")}}', - name: 'popup', - Component: 'PopupActionInitializer', - }, - { - type: 'item', - title: '{{t("Update record")}}', - name: 'updateRecord', - Component: 'UpdateRecordActionInitializer', - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - { - name: 'customRequest', - title: '{{t("Custom request")}}', - Component: 'CustomRequestInitializer', - schema: { - 'x-action': 'customize:table:request', - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - ], - }, - { - name: 'divider2', - type: 'divider', + sort: 100, }, { name: 'fixed', title: 't("Fixed")', type: 'item', Component: SchemaSettingsFixed, + sort: 100, }, { type: 'item', name: 'columnWidth', title: 't("Column width")', Component: Resizable, + sort: 100, }, ], }; diff --git a/packages/core/client/src/modules/blocks/data-blocks/table/TableActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/table/TableActionInitializers.tsx index 2aba165eb8..2b80872136 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/table/TableActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/table/TableActionInitializers.tsx @@ -11,13 +11,7 @@ import { useFieldSchema } from '@formily/react'; import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer'; import { useCollection_deprecated } from '../../../../collection-manager/hooks/useCollection_deprecated'; -/** - * @deprecated - * use `tableActionInitializers` instead - * 表格操作配置 - */ -export const tableActionInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'TableActionInitializers', +const commonOptions = { title: "{{t('Configure actions')}}", icon: 'SettingOutlined', style: { @@ -25,224 +19,85 @@ export const tableActionInitializers_deprecated = new CompatibleSchemaInitialize }, items: [ { - type: 'itemGroup', - name: 'enableActions', - title: "{{t('Enable actions')}}", - children: [ - { - type: 'item', - name: 'filter', - title: "{{t('Filter')}}", - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'left', - }, - }, - { - type: 'item', - title: "{{t('Add new')}}", - name: 'addNew', - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'file', 'sql'].includes(collection.template) || collection?.writableView; - }, - }, - { - type: 'item', - title: "{{t('Delete')}}", - name: 'delete', - Component: 'BulkDestroyActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - }, - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'sql'].includes(collection.template) || collection?.writableView; - }, - }, - { - type: 'item', - title: "{{t('Refresh')}}", - name: 'refresh', - Component: 'RefreshActionInitializer', - schema: { - 'x-align': 'right', - }, - }, - { - name: 'toggle', - title: "{{t('Expand/Collapse')}}", - Component: 'ExpandableActionInitializer', - schema: { - 'x-align': 'right', - }, - useVisible() { - const schema = useFieldSchema(); - const collection = useCollection_deprecated(); - const { treeTable } = schema?.parent?.['x-decorator-props'] || {}; - return collection.tree && treeTable; - }, - }, - ], + type: 'item', + name: 'filter', + title: "{{t('Filter')}}", + Component: 'FilterActionInitializer', + schema: { + 'x-align': 'left', + }, }, { - name: 'divider', - type: 'divider', + type: 'item', + title: "{{t('Add new')}}", + name: 'addNew', + Component: 'CreateActionInitializer', + schema: { + 'x-align': 'right', + 'x-decorator': 'ACLActionProvider', + 'x-acl-action-props': { + skipScopeCheck: true, + }, + }, + useVisible() { + const collection = useCollection_deprecated(); + return !['view', 'file', 'sql'].includes(collection.template) || collection?.writableView; + }, + }, + { + type: 'item', + title: "{{t('Delete')}}", + name: 'delete', + Component: 'BulkDestroyActionInitializer', + schema: { + 'x-align': 'right', + 'x-decorator': 'ACLActionProvider', + }, useVisible() { const collection = useCollection_deprecated(); return !['view', 'sql'].includes(collection.template) || collection?.writableView; }, }, { - type: 'subMenu', - name: 'customize', - title: '{{t("Customize")}}', - children: [ - { - type: 'item', - title: '{{t("Add record")}}', - name: 'addRecord', - Component: 'CustomizeAddRecordActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action': 'create', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - }, - ], + type: 'item', + title: "{{t('Refresh')}}", + name: 'refresh', + Component: 'RefreshActionInitializer', + schema: { + 'x-align': 'right', + }, + }, + { + name: 'toggle', + title: "{{t('Expand/Collapse')}}", + Component: 'ExpandableActionInitializer', + schema: { + 'x-align': 'right', + }, useVisible() { + const schema = useFieldSchema(); const collection = useCollection_deprecated(); - return !['view', 'sql'].includes(collection.template) || collection?.writableView; + const { treeTable } = schema?.parent?.['x-decorator-props'] || {}; + return collection.tree && treeTable; }, }, ], +}; + +/** + * @deprecated + * use `tableActionInitializers` instead + * 表格操作配置 + */ +export const tableActionInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'TableActionInitializers', + ...commonOptions, }); export const tableActionInitializers = new CompatibleSchemaInitializer( { name: 'table:configureActions', - title: "{{t('Configure actions')}}", - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'itemGroup', - name: 'enableActions', - title: "{{t('Enable actions')}}", - children: [ - { - type: 'item', - name: 'filter', - title: "{{t('Filter')}}", - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'left', - }, - }, - { - type: 'item', - title: "{{t('Add new')}}", - name: 'addNew', - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'file', 'sql'].includes(collection.template) || collection?.writableView; - }, - }, - { - type: 'item', - title: "{{t('Delete')}}", - name: 'delete', - Component: 'BulkDestroyActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - }, - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'sql'].includes(collection.template) || collection?.writableView; - }, - }, - { - type: 'item', - title: "{{t('Refresh')}}", - name: 'refresh', - Component: 'RefreshActionInitializer', - schema: { - 'x-align': 'right', - }, - }, - { - name: 'toggle', - title: "{{t('Expand/Collapse')}}", - Component: 'ExpandableActionInitializer', - schema: { - 'x-align': 'right', - }, - useVisible() { - const schema = useFieldSchema(); - const collection = useCollection_deprecated(); - const { treeTable } = schema?.parent?.['x-decorator-props'] || {}; - return collection.tree && treeTable; - }, - }, - ], - }, - { - name: 'divider', - type: 'divider', - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'sql'].includes(collection.template) || collection?.writableView; - }, - }, - { - type: 'subMenu', - name: 'customize', - title: '{{t("Customize")}}', - children: [ - { - type: 'item', - title: '{{t("Add record")}}', - name: 'addRecord', - Component: 'CustomizeAddRecordActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action': 'create', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - }, - ], - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'sql'].includes(collection.template) || collection?.writableView; - }, - }, - ], + ...commonOptions, }, tableActionInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaInitializer.test.ts b/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaInitializer.test.ts index a9088cb2a8..97d3d15618 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaInitializer.test.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaInitializer.test.ts @@ -7,9 +7,16 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { expect, oneEmptyTable, test } from '@nocobase/test/e2e'; +import { Page, expect, oneEmptyTable, test } from '@nocobase/test/e2e'; import { oneTableWithInheritFields } from './templatesOfBug'; +const deleteButton = async (page: Page, name: string) => { + await page.getByLabel(`action-Action.Link-${name}-`).hover(); + await page.getByLabel(`action-Action.Link-${name}-`).getByLabel('designer-schema-settings-').hover(); + await page.getByRole('menuitem', { name: 'Delete' }).click(); + await page.getByRole('button', { name: 'OK', exact: true }).click(); +}; + test.describe('configure columns', () => { // 该用例在 CI 并发环境下容易报错,原因未知,通过增加重试次数可以解决 test.describe.configure({ retries: process.env.CI ? 4 : 0 }); @@ -135,11 +142,6 @@ test.describe('configure actions column', () => { await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Duplicate' }).click(); - await expect(page.getByRole('menuitem', { name: 'View' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Duplicate' }).getByRole('switch')).toBeChecked(); - await page.mouse.move(300, 0); await expect(page.getByLabel('action-Action.Link-View-view-t_unp4scqamw9-table-0')).toBeVisible(); await expect(page.getByLabel('action-Action.Link-Edit-update-t_unp4scqamw9-table-0')).toBeVisible(); @@ -147,17 +149,10 @@ test.describe('configure actions column', () => { await expect(page.getByLabel('action-Action.Link-Duplicate-duplicate-t_unp4scqamw9-table-0')).toBeVisible(); // delete view & Edit & Delete & Duplicate ------------------------------------------------------------ - await page.getByText('Actions', { exact: true }).hover(); - await page.getByLabel('designer-schema-settings-TableV2.Column-TableV2.ActionColumnDesigner-t_unp4scqamw9').hover(); - await page.getByRole('menuitem', { name: 'View' }).click(); - await page.getByRole('menuitem', { name: 'Edit' }).click(); - await page.getByRole('menuitem', { name: 'Delete' }).click(); - await page.getByRole('menuitem', { name: 'Duplicate' }).click(); - - await expect(page.getByRole('menuitem', { name: 'View' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Edit' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Duplicate' }).getByRole('switch')).not.toBeChecked(); + await deleteButton(page, 'View'); + await deleteButton(page, 'Edit'); + await deleteButton(page, 'Delete'); + await deleteButton(page, 'Duplicate'); await page.mouse.move(300, 0); await expect(page.getByLabel('action-Action.Link-View-view-t_unp4scqamw9-table-0')).not.toBeVisible(); @@ -168,7 +163,6 @@ test.describe('configure actions column', () => { // add custom action ------------------------------------------------------------ await page.getByText('Actions', { exact: true }).hover(); await page.getByLabel('designer-schema-settings-TableV2.Column-TableV2.ActionColumnDesigner-t_unp4scqamw9').hover(); - await page.getByRole('menuitem', { name: 'Customize' }).hover(); await page.getByRole('menuitem', { name: 'Popup' }).click(); // 此时二级菜单,不应该关闭,可以继续点击? diff --git a/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaInitializer1.test.ts b/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaInitializer1.test.ts index d4ad84569a..c452e16325 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaInitializer1.test.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaInitializer1.test.ts @@ -7,9 +7,16 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { createBlockInPage, expect, oneEmptyTable, test } from '@nocobase/test/e2e'; +import { Page, createBlockInPage, expect, oneEmptyTable, test } from '@nocobase/test/e2e'; import { T3686, T4005 } from './templatesOfBug'; +const deleteButton = async (page: Page, name: string) => { + await page.getByRole('button', { name }).hover(); + await page.getByRole('button', { name }).getByLabel('designer-schema-settings-').hover(); + await page.getByRole('menuitem', { name: 'Delete' }).click(); + await page.getByRole('button', { name: 'OK', exact: true }).click(); +}; + test.describe('where table block can be added', () => { test('page', async ({ page, mockPage }) => { await mockPage().goto(); @@ -116,11 +123,6 @@ test.describe('configure actions', () => { await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Refresh' }).click(); - await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).toBeChecked(); - await page.mouse.move(300, 0); await expect(page.getByRole('button', { name: 'Filter' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Add new' })).toBeVisible(); @@ -128,16 +130,10 @@ test.describe('configure actions', () => { await expect(page.getByRole('button', { name: 'Refresh' })).toBeVisible(); // delete buttons - await page.getByLabel('schema-initializer-ActionBar-table:configureActions-t_unp4scqamw9').hover(); - await page.getByRole('menuitem', { name: 'Filter' }).click(); - await page.getByRole('menuitem', { name: 'Add new' }).click(); - await page.getByRole('menuitem', { name: 'Delete' }).click(); - await page.getByRole('menuitem', { name: 'Refresh' }).click(); - - await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Delete' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Refresh' }).getByRole('switch')).not.toBeChecked(); + await deleteButton(page, 'Filter'); + await deleteButton(page, 'Add new'); + await deleteButton(page, 'Delete'); + await deleteButton(page, 'Refresh'); await page.mouse.move(300, 0); await expect(page.getByRole('button', { name: 'Filter' })).not.toBeVisible(); @@ -145,15 +141,4 @@ test.describe('configure actions', () => { await expect(page.getByRole('button', { name: 'Delete' })).not.toBeVisible(); await expect(page.getByRole('button', { name: 'Refresh' })).not.toBeVisible(); }); - - test('customize: add record', async ({ page, mockPage }) => { - await mockPage(oneEmptyTable).goto(); - - await page.getByLabel('schema-initializer-ActionBar-table:configureActions-t_unp4scqamw9').hover(); - await page.getByRole('menuitem', { name: 'Customize' }).hover(); - await page.getByRole('menuitem', { name: 'add record' }).click(); - - await page.mouse.move(300, 0); - await expect(page.getByRole('button', { name: 'Add record' })).toBeVisible(); - }); }); diff --git a/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaSettings.test.ts b/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaSettings.test.ts index 514cac5f34..1d928d7b23 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaSettings.test.ts +++ b/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/schemaSettings.test.ts @@ -19,6 +19,27 @@ import { } from '@nocobase/test/e2e'; import { T3843, oneTableWithColumnFixed, oneTableWithUpdateRecord } from './templatesOfBug'; +const addSomeCustomActions = async (page: Page) => { + // 先删除掉之前的 actions + const deleteAction = async (name: string) => { + await page.getByLabel(`action-Action.Link-${name}-`).hover(); + await page.getByRole('button', { name: 'designer-schema-settings-Action.Link-Action.Designer-general' }).hover(); + await page.getByRole('menuitem', { name: 'Delete' }).click(); + await page.getByRole('button', { name: 'OK', exact: true }).click(); + }; + + await deleteAction('View'); + await deleteAction('Edit'); + await deleteAction('Delete'); + await deleteAction('Duplicate'); + + // 再增加两个自定义的 actions + await page.getByRole('button', { name: 'Actions', exact: true }).hover(); + await page.getByLabel('designer-schema-settings-TableV2.Column-TableV2.ActionColumnDesigner-general').hover(); + await page.getByRole('menuitem', { name: 'Popup' }).click(); + await page.getByRole('menuitem', { name: 'Update record' }).click(); +}; + test.describe('actions schema settings', () => { test.describe('add new', () => { const showMenu = async (page: Page) => { @@ -295,21 +316,6 @@ test.describe('actions schema settings', () => { }); test.describe('popup', () => { - const addSomeCustomActions = async (page: Page) => { - // 先删除掉之前的 actions - await page.getByRole('button', { name: 'Actions', exact: true }).hover(); - await page.getByLabel('designer-schema-settings-TableV2.Column-TableV2.ActionColumnDesigner-general').hover(); - await page.getByRole('menuitem', { name: 'View' }).click(); - await page.getByRole('menuitem', { name: 'Edit' }).click(); - await page.getByRole('menuitem', { name: 'Delete' }).click(); - await page.getByRole('menuitem', { name: 'Duplicate' }).click(); - - // 再增加两个自定义的 actions - await page.getByRole('menuitem', { name: 'Customize' }).hover(); - await page.getByRole('menuitem', { name: 'Popup' }).click(); - await page.getByRole('menuitem', { name: 'Update record' }).click(); - }; - const showMenu = async (page: Page) => { await page.getByLabel('action-Action.Link-Popup-customize:popup-general-table-0').hover(); await page @@ -352,21 +358,6 @@ test.describe('actions schema settings', () => { }); test.describe('update record', () => { - const addSomeCustomActions = async (page: Page) => { - // 先删除掉之前的 actions - await page.getByRole('button', { name: 'Actions', exact: true }).hover(); - await page.getByLabel('designer-schema-settings-TableV2.Column-TableV2.ActionColumnDesigner-general').hover(); - await page.getByRole('menuitem', { name: 'View' }).click(); - await page.getByRole('menuitem', { name: 'Edit' }).click(); - await page.getByRole('menuitem', { name: 'Delete' }).click(); - await page.getByRole('menuitem', { name: 'Duplicate' }).click(); - - // 再增加两个自定义的 actions - await page.getByRole('menuitem', { name: 'Customize' }).hover(); - await page.getByRole('menuitem', { name: 'Popup' }).click(); - await page.getByRole('menuitem', { name: 'Update record' }).click(); - }; - const showMenu = async (page: Page) => { await page.getByLabel('action-Action.Link-Update record-customize:update-general-table-0').hover(); await page @@ -403,7 +394,6 @@ test.describe('actions schema settings', () => { if (!(await page.getByLabel('action-Action.Link-Update record-customize:update-users2-table-0').isVisible())) { await page.getByRole('button', { name: 'Actions', exact: true }).hover(); await page.getByLabel('designer-schema-settings-TableV2.Column-TableV2.ActionColumnDesigner-users2').hover(); - await page.getByRole('menuitem', { name: 'Customize right' }).hover(); await page.getByRole('menuitem', { name: 'Update record' }).click(); } @@ -473,7 +463,8 @@ test.describe('actions schema settings', () => { await page.getByRole('menuitem', { name: 'Add new' }).click(); await page.getByRole('button', { name: 'Add new' }).click(); await page.getByLabel('schema-initializer-Grid-popup:addNew:addBlock-treeCollection').hover(); - await page.getByRole('menuitem', { name: 'form Form' }).click(); + await page.getByRole('menuitem', { name: 'form Form' }).hover(); + await page.getByRole('menuitem', { name: 'Current collection' }).click(); await page.mouse.move(300, 0); await page.getByLabel('schema-initializer-ActionBar-createForm:configureActions-treeCollection').hover(); await page.getByRole('menuitem', { name: 'Submit' }).click(); @@ -500,7 +491,8 @@ test.describe('actions schema settings', () => { position: { x: 5, y: 5 }, // 防止按钮被遮挡 }); await page.getByLabel('schema-initializer-Grid-popup').hover(); - await page.getByRole('menuitem', { name: 'form Form' }).click(); + await page.getByRole('menuitem', { name: 'form Form' }).hover(); + await page.getByRole('menuitem', { name: 'Current collection' }).click(); await page.mouse.move(300, 0); await page.getByLabel('schema-initializer-Grid-form:').hover(); await page.getByRole('menuitem', { name: 'Parent', exact: true }).click(); diff --git a/packages/core/client/src/modules/blocks/filter-blocks/form/FilterFormActionInitializers.tsx b/packages/core/client/src/modules/blocks/filter-blocks/form/FilterFormActionInitializers.tsx index 5d981e8b36..97ed64e269 100644 --- a/packages/core/client/src/modules/blocks/filter-blocks/form/FilterFormActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/filter-blocks/form/FilterFormActionInitializers.tsx @@ -8,6 +8,28 @@ */ import { CompatibleSchemaInitializer } from '../../../../application/schema-initializer/CompatibleSchemaInitializer'; +const commonOptions = { + title: '{{t("Configure actions")}}', + icon: 'SettingOutlined', + items: [ + { + name: 'filter', + title: '{{t("Filter")}}', + Component: 'CreateFilterActionInitializer', + schema: { + 'x-action-settings': {}, + }, + }, + { + name: 'reset', + title: '{{t("Reset")}}', + Component: 'CreateResetActionInitializer', + schema: { + 'x-action-settings': {}, + }, + }, + ], +}; /** * @deprecated @@ -16,65 +38,13 @@ import { CompatibleSchemaInitializer } from '../../../../application/schema-init */ export const filterFormActionInitializers_deprecated = new CompatibleSchemaInitializer({ name: 'FilterFormActionInitializers', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - items: [ - { - type: 'itemGroup', - title: '{{t("Enable actions")}}', - name: 'enableActions', - children: [ - { - name: 'filter', - title: '{{t("Filter")}}', - Component: 'CreateFilterActionInitializer', - schema: { - 'x-action-settings': {}, - }, - }, - { - name: 'reset', - title: '{{t("Reset")}}', - Component: 'CreateResetActionInitializer', - schema: { - 'x-action-settings': {}, - }, - }, - ], - }, - ], + ...commonOptions, }); export const filterFormActionInitializers = new CompatibleSchemaInitializer( { name: 'filterForm:configureActions', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - items: [ - { - type: 'itemGroup', - title: '{{t("Enable actions")}}', - name: 'enableActions', - children: [ - { - name: 'filter', - title: '{{t("Filter")}}', - Component: 'CreateFilterActionInitializer', - schema: { - 'x-action-settings': {}, - }, - }, - { - name: 'reset', - title: '{{t("Reset")}}', - Component: 'CreateResetActionInitializer', - schema: { - 'x-action-settings': {}, - }, - }, - ], - }, - ], + ...commonOptions, }, filterFormActionInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/blocks/filter-blocks/form/__e2e__/schemaInitializer.test.ts b/packages/core/client/src/modules/blocks/filter-blocks/form/__e2e__/schemaInitializer.test.ts index d12fdec0fc..bc07053c3d 100644 --- a/packages/core/client/src/modules/blocks/filter-blocks/form/__e2e__/schemaInitializer.test.ts +++ b/packages/core/client/src/modules/blocks/filter-blocks/form/__e2e__/schemaInitializer.test.ts @@ -7,9 +7,16 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { createBlockInPage, expect, oneEmptyFilterFormBlock, test } from '@nocobase/test/e2e'; +import { Page, createBlockInPage, expect, oneEmptyFilterFormBlock, test } from '@nocobase/test/e2e'; import { oneFilterFormWithInherit } from './templatesOfBug'; +const deleteButton = async (page: Page, name: string) => { + await page.getByLabel(`action-Action-${name}-`).hover(); + await page.getByLabel(`action-Action-${name}-`).getByLabel('designer-schema-settings-').hover(); + await page.getByRole('menuitem', { name: 'Delete' }).click(); + await page.getByRole('button', { name: 'OK', exact: true }).click(); +}; + test.describe('where filter form block can be added', () => { test('page', async ({ page, mockPage }) => { await mockPage().goto(); @@ -104,21 +111,13 @@ test.describe('configure actions', () => { await page.getByRole('menuitem', { name: 'Filter' }).click(); await page.getByRole('menuitem', { name: 'Reset' }).click(); - await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Reset' }).getByRole('switch')).toBeChecked(); - await page.mouse.move(300, 0); await expect(page.getByLabel('action-Action-Filter-submit-general-filter-form')).toBeVisible(); await expect(page.getByLabel('action-Action-Reset-general-filter-form')).toBeVisible(); // delete buttons - await page.getByLabel('schema-initializer-ActionBar-filterForm:configureActions-general').hover(); - await page.getByRole('menuitem', { name: 'Filter' }).click(); - await page.getByRole('menuitem', { name: 'Reset' }).click(); - - await expect(page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch')).not.toBeChecked(); - await expect(page.getByRole('menuitem', { name: 'Reset' }).getByRole('switch')).not.toBeChecked(); - + await deleteButton(page, 'Filter'); + await deleteButton(page, 'Reset'); await page.mouse.move(300, 0); await expect(page.getByLabel('action-Action-Filter-submit-general-filter-form')).not.toBeVisible(); await expect(page.getByLabel('action-Action-Reset-general-filter-form')).not.toBeVisible(); diff --git a/packages/core/client/src/modules/blocks/filter-blocks/form/filterFormItemInitializers.tsx b/packages/core/client/src/modules/blocks/filter-blocks/form/filterFormItemInitializers.tsx index 0d0382d661..63ab0e958e 100644 --- a/packages/core/client/src/modules/blocks/filter-blocks/form/filterFormItemInitializers.tsx +++ b/packages/core/client/src/modules/blocks/filter-blocks/form/filterFormItemInitializers.tsx @@ -14,12 +14,7 @@ import { } from '../../../../schema-initializer/buttons/FormItemInitializers'; import { gridRowColWrap, useFilterFormItemInitializerFields } from '../../../../schema-initializer/utils'; -/** - * @deprecated - * use `filterFormItemInitializers` instead - */ -export const filterFormItemInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'FilterFormItemInitializers', +const commonOptions = { wrap: gridRowColWrap, icon: 'SettingOutlined', title: '{{t("Configure fields")}}', @@ -48,39 +43,21 @@ export const filterFormItemInitializers_deprecated = new CompatibleSchemaInitial name: 'addText', }, ], +}; + +/** + * @deprecated + * use `filterFormItemInitializers` instead + */ +export const filterFormItemInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'FilterFormItemInitializers', + ...commonOptions, }); export const filterFormItemInitializers = new CompatibleSchemaInitializer( { name: 'filterForm:configureFields', - wrap: gridRowColWrap, - icon: 'SettingOutlined', - title: '{{t("Configure fields")}}', - items: [ - { - type: 'itemGroup', - name: 'displayFields', - title: '{{t("Display fields")}}', - useChildren: useFilterFormItemInitializerFields, - }, - { - name: 'parentCollectionFields', - Component: FilterParentCollectionFields, - }, - { - name: 'associationFields', - Component: FilterAssociatedFields, - }, - { - name: 'divider', - type: 'divider', - }, - { - title: '{{t("Add text")}}', - Component: 'MarkdownFormItemInitializer', - name: 'addText', - }, - ], + ...commonOptions, }, filterFormItemInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/page/BlockInitializers.tsx b/packages/core/client/src/modules/page/BlockInitializers.tsx index e66c7cc2b1..ac1e6c07f8 100644 --- a/packages/core/client/src/modules/page/BlockInitializers.tsx +++ b/packages/core/client/src/modules/page/BlockInitializers.tsx @@ -10,12 +10,7 @@ import { CompatibleSchemaInitializer } from '../../application/schema-initializer/CompatibleSchemaInitializer'; import { gridRowColWrap } from '../../schema-initializer/utils'; -/** - * @deprecated - * use `blockInitializers` instead - */ -export const blockInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'BlockInitializers', +const commonOptions = { title: '{{t("Add block")}}', icon: 'PlusOutlined', wrap: gridRowColWrap, @@ -82,77 +77,21 @@ export const blockInitializers_deprecated = new CompatibleSchemaInitializer({ ], }, ], +}; + +/** + * @deprecated + * use `blockInitializers` instead + */ +export const blockInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'BlockInitializers', + ...commonOptions, }); export const blockInitializers = new CompatibleSchemaInitializer( { name: 'page:addBlock', - title: '{{t("Add block")}}', - icon: 'PlusOutlined', - wrap: gridRowColWrap, - items: [ - { - name: 'dataBlocks', - title: '{{t("Data blocks")}}', - type: 'itemGroup', - children: [ - { - name: 'table', - title: '{{t("Table")}}', - Component: 'TableBlockInitializer', - }, - { - name: 'form', - title: '{{t("Form")}}', - Component: 'FormBlockInitializer', - }, - { - name: 'details', - title: '{{t("Details")}}', - Component: 'DetailsBlockInitializer', - }, - { - name: 'list', - title: '{{t("List")}}', - Component: 'ListBlockInitializer', - }, - { - name: 'gridCard', - title: '{{t("Grid Card")}}', - Component: 'GridCardBlockInitializer', - }, - ], - }, - { - name: 'filterBlocks', - title: '{{t("Filter blocks")}}', - type: 'itemGroup', - children: [ - { - name: 'filterForm', - title: '{{t("Form")}}', - Component: 'FilterFormBlockInitializer', - }, - { - name: 'filterCollapse', - title: '{{t("Collapse")}}', - Component: 'FilterCollapseBlockInitializer', - }, - ], - }, - { - name: 'otherBlocks', - type: 'itemGroup', - title: '{{t("Other blocks")}}', - children: [ - { - name: 'markdown', - title: '{{t("Markdown")}}', - Component: 'MarkdownBlockInitializer', - }, - ], - }, - ], + ...commonOptions, }, blockInitializers_deprecated, ); diff --git a/packages/core/client/src/modules/popup/__e2e__/schemaInitializer1.test.ts b/packages/core/client/src/modules/popup/__e2e__/schemaInitializer1.test.ts index ac25bbb4c7..044b3e1afd 100644 --- a/packages/core/client/src/modules/popup/__e2e__/schemaInitializer1.test.ts +++ b/packages/core/client/src/modules/popup/__e2e__/schemaInitializer1.test.ts @@ -33,8 +33,9 @@ test.describe('where to open a popup and what can be added to it', () => { // add blocks await page.getByLabel('schema-initializer-Grid-popup:addNew:addBlock-general').hover(); - await page.getByText('Form').click(); await page.getByText('Markdown').click(); + await page.getByText('Form').hover(); + await page.getByRole('menuitem', { name: 'Current collection' }).click(); await page.mouse.move(300, 0); diff --git a/packages/core/client/src/schema-component/antd/association-filter/ActionBarAssociationFilterAction.tsx b/packages/core/client/src/schema-component/antd/association-filter/ActionBarAssociationFilterAction.tsx index fb915b0b5e..6937249a0d 100644 --- a/packages/core/client/src/schema-component/antd/association-filter/ActionBarAssociationFilterAction.tsx +++ b/packages/core/client/src/schema-component/antd/association-filter/ActionBarAssociationFilterAction.tsx @@ -14,7 +14,7 @@ import { SchemaComponentContext, createDesignable } from '../..'; import { useAPIClient } from '../../../api-client'; import { useBlockRequestContext } from '../../../block-provider'; import { mergeFilter } from '../../../filter-provider/utils'; -import { ActionInitializer } from '../../../schema-initializer/items/ActionInitializer'; +import { ActionInitializerItem } from '../../../schema-initializer/items/ActionInitializerItem'; /** * @deprecated @@ -58,5 +58,5 @@ export const ActionBarAssociationFilterAction = (props) => { wrap: (s) => s, }; - return ; + return ; }; diff --git a/packages/core/client/src/schema-initializer/buttons/CustomFormItemInitializers.tsx b/packages/core/client/src/schema-initializer/buttons/CustomFormItemInitializers.tsx index 7da258acde..b573b172cf 100644 --- a/packages/core/client/src/schema-initializer/buttons/CustomFormItemInitializers.tsx +++ b/packages/core/client/src/schema-initializer/buttons/CustomFormItemInitializers.tsx @@ -33,12 +33,7 @@ const ParentCollectionFields = () => { return {res}; }; -/** - * @deprecated - * use `customFormItemInitializers` instead - */ -export const customFormItemInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'CustomFormItemInitializers', +const commonOptions = { wrap: gridRowColWrap, icon: 'SettingOutlined', title: '{{t("Configure fields")}}', @@ -54,26 +49,21 @@ export const customFormItemInitializers_deprecated = new CompatibleSchemaInitial Component: ParentCollectionFields, }, ], +}; + +/** + * @deprecated + * use `customFormItemInitializers` instead + */ +export const customFormItemInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'CustomFormItemInitializers', + ...commonOptions, }); export const customFormItemInitializers = new CompatibleSchemaInitializer( { name: 'assignFieldValuesForm:configureFields', - wrap: gridRowColWrap, - icon: 'SettingOutlined', - title: '{{t("Configure fields")}}', - items: [ - { - type: 'itemGroup', - title: '{{t("Configure fields")}}', - name: 'configureFields', - useChildren: useCustomFormItemInitializerFields, - }, - { - name: 'parentCollectionFields', - Component: ParentCollectionFields, - }, - ], + ...commonOptions, }, customFormItemInitializers_deprecated, ); diff --git a/packages/core/client/src/schema-initializer/buttons/RecordBlockInitializers.tsx b/packages/core/client/src/schema-initializer/buttons/RecordBlockInitializers.tsx index 1d0105a5af..e9feca2c94 100644 --- a/packages/core/client/src/schema-initializer/buttons/RecordBlockInitializers.tsx +++ b/packages/core/client/src/schema-initializer/buttons/RecordBlockInitializers.tsx @@ -170,13 +170,13 @@ function useRecordBlocks() { componentType: 'FormItem', createBlockSchema: ({ item, fromOthersInPopup }) => { if (fromOthersInPopup) { - return createFormBlock({ item }); + return createFormBlock({ item, fromOthersInPopup }); } createAssociationFormBlock({ item }); }, templateWrap: (templateSchema, { item, fromOthersInPopup }) => { if (fromOthersInPopup) { - return templateWrapCollection(templateSchema, { item }); + return templateWrapCollection(templateSchema, { item, fromOthersInPopup }); } templateWrap(templateSchema, { item }); }, diff --git a/packages/core/client/src/schema-initializer/buttons/SubTableActionInitializers.tsx b/packages/core/client/src/schema-initializer/buttons/SubTableActionInitializers.tsx index c9281987f3..520e092c72 100644 --- a/packages/core/client/src/schema-initializer/buttons/SubTableActionInitializers.tsx +++ b/packages/core/client/src/schema-initializer/buttons/SubTableActionInitializers.tsx @@ -9,13 +9,7 @@ import { CompatibleSchemaInitializer } from '../../application/schema-initializer/CompatibleSchemaInitializer'; -/** - * @deprecated - * use `subTableActionInitializers` instead - * 表格操作配置 - */ -export const subTableActionInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'SubTableActionInitializers', +const commonOptions = { title: "{{t('Configure actions')}}", icon: 'SettingOutlined', style: { @@ -46,41 +40,22 @@ export const subTableActionInitializers_deprecated = new CompatibleSchemaInitial ], }, ], +}; + +/** + * @deprecated + * use `subTableActionInitializers` instead + * 表格操作配置 + */ +export const subTableActionInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'SubTableActionInitializers', + ...commonOptions, }); export const subTableActionInitializers = new CompatibleSchemaInitializer( { name: 'subTable:configureActions', - title: "{{t('Configure actions')}}", - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'itemGroup', - title: "{{t('Enable actions')}}", - name: 'enableActions', - children: [ - { - name: 'addNew', - title: "{{t('Add new')}}", - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - }, - }, - { - name: 'delete', - title: "{{t('Delete')}}", - Component: 'BulkDestroyActionInitializer', - schema: { - 'x-align': 'right', - }, - }, - ], - }, - ], + ...commonOptions, }, subTableActionInitializers_deprecated, ); diff --git a/packages/core/client/src/schema-initializer/index.ts b/packages/core/client/src/schema-initializer/index.ts index bc70539f3d..1860127995 100644 --- a/packages/core/client/src/schema-initializer/index.ts +++ b/packages/core/client/src/schema-initializer/index.ts @@ -14,7 +14,6 @@ import { createFormBlockInitializers, createFormBlockInitializers_deprecated, } from '../modules/actions/add-new/createFormBlockInitializers'; -import { CustomizeAddRecordActionInitializer } from '../modules/actions/add-record/CustomizeAddRecordActionInitializer'; import { customizeCreateFormBlockInitializers, customizeCreateFormBlockInitializers_deprecated, @@ -25,7 +24,6 @@ import { DisassociateActionInitializer } from '../modules/actions/disassociate/D import { ExpandableActionInitializer } from '../modules/actions/expand-collapse/ExpandableActionInitializer'; import { FilterActionInitializer } from '../modules/actions/filter/FilterActionInitializer'; import { RefreshActionInitializer } from '../modules/actions/refresh/RefreshActionInitializer'; -import { SaveRecordActionInitializer } from '../modules/actions/save-record/SaveRecordActionInitializer'; import { CreateSubmitActionInitializer } from '../modules/actions/submit/CreateSubmitActionInitializer'; import { UpdateSubmitActionInitializer } from '../modules/actions/submit/UpdateSubmitActionInitializer'; import { UpdateRecordActionInitializer } from '../modules/actions/update-record/UpdateRecordActionInitializer'; @@ -47,7 +45,6 @@ import { readPrettyFormItemInitializers_deprecated, } from '../modules/blocks/data-blocks/details-single/ReadPrettyFormItemInitializers'; import { RecordReadPrettyFormBlockInitializer } from '../modules/blocks/data-blocks/details-single/RecordReadPrettyFormBlockInitializer'; -import { CreateFormBlockInitializer } from '../modules/blocks/data-blocks/form/CreateFormBlockInitializer'; import { FormBlockInitializer } from '../modules/blocks/data-blocks/form/FormBlockInitializer'; import { RecordFormBlockInitializer } from '../modules/blocks/data-blocks/form/RecordFormBlockInitializer'; import { @@ -155,7 +152,6 @@ export class SchemaInitializerPlugin extends Plugin { ...initializerComponents, ...items, DestroyActionInitializer, - CreateFormBlockInitializer, FormBlockInitializer, RecordFormBlockInitializer, TableBlockInitializer, @@ -171,12 +167,10 @@ export class SchemaInitializerPlugin extends Plugin { TableCollectionFieldInitializer, CollectionFieldInitializer, CreateActionInitializer, - CustomizeAddRecordActionInitializer, CreateChildInitializer, ViewActionInitializer, UpdateActionInitializer, PopupActionInitializer, - SaveRecordActionInitializer, UpdateRecordActionInitializer, CreateSubmitActionInitializer, UpdateSubmitActionInitializer, diff --git a/packages/core/client/src/schema-initializer/items/ActionInitializer.tsx b/packages/core/client/src/schema-initializer/items/ActionInitializer.tsx index c16d72a95a..d0001711e4 100644 --- a/packages/core/client/src/schema-initializer/items/ActionInitializer.tsx +++ b/packages/core/client/src/schema-initializer/items/ActionInitializer.tsx @@ -9,9 +9,15 @@ import React from 'react'; -import { InitializerWithSwitch } from './InitializerWithSwitch'; import { useSchemaInitializerItem } from '../../application'; +import { InitializerWithSwitch } from './InitializerWithSwitch'; +/** + * @deprecated + * use ActionInitializerItem instead + * @param props + * @returns + */ export const ActionInitializer = (props) => { const itemConfig = useSchemaInitializerItem(); return ; diff --git a/packages/core/client/src/schema-initializer/items/ActionInitializerItem.tsx b/packages/core/client/src/schema-initializer/items/ActionInitializerItem.tsx new file mode 100644 index 0000000000..fca950a258 --- /dev/null +++ b/packages/core/client/src/schema-initializer/items/ActionInitializerItem.tsx @@ -0,0 +1,29 @@ +/** + * 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 { merge } from '@formily/shared'; +import React from 'react'; + +import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '../../application'; + +export const ActionInitializerItem = (props) => { + const itemConfig = useSchemaInitializerItem(); + const { insert } = useSchemaInitializer(); + + return ( + { + const s = merge(props.schema || {}, itemConfig.schema || {}); + itemConfig?.schemaInitialize?.(s); + insert(s); + }} + /> + ); +}; diff --git a/packages/core/client/src/schema-initializer/items/CreateFilterActionInitializer.tsx b/packages/core/client/src/schema-initializer/items/CreateFilterActionInitializer.tsx index b2034fb111..2f57d9eb43 100644 --- a/packages/core/client/src/schema-initializer/items/CreateFilterActionInitializer.tsx +++ b/packages/core/client/src/schema-initializer/items/CreateFilterActionInitializer.tsx @@ -8,7 +8,6 @@ */ import React from 'react'; - import { ActionInitializer } from './ActionInitializer'; export const CreateFilterActionInitializer = (props) => { diff --git a/packages/core/client/src/schema-initializer/items/CreateResetActionInitializer.tsx b/packages/core/client/src/schema-initializer/items/CreateResetActionInitializer.tsx index 0e4b007917..6670e162ed 100644 --- a/packages/core/client/src/schema-initializer/items/CreateResetActionInitializer.tsx +++ b/packages/core/client/src/schema-initializer/items/CreateResetActionInitializer.tsx @@ -8,7 +8,6 @@ */ import React from 'react'; - import { ActionInitializer } from './ActionInitializer'; export const CreateResetActionInitializer = (props) => { diff --git a/packages/core/client/src/schema-initializer/items/DataBlockInitializer.tsx b/packages/core/client/src/schema-initializer/items/DataBlockInitializer.tsx index 9e4893cd5b..ad3a42e5e5 100644 --- a/packages/core/client/src/schema-initializer/items/DataBlockInitializer.tsx +++ b/packages/core/client/src/schema-initializer/items/DataBlockInitializer.tsx @@ -301,6 +301,10 @@ export interface DataBlockInitializerProps { */ hideOtherRecordsInPopup?: boolean; onClick?: (args: any) => void; + /** 用于更改 Current record 的文案 */ + currentText?: string; + /** 用于更改 Other records 的文案 */ + otherText?: string; } export const DataBlockInitializer = (props: DataBlockInitializerProps) => { @@ -321,6 +325,8 @@ export const DataBlockInitializer = (props: DataBlockInitializerProps) => { hideOtherRecordsInPopup, onClick: propsOnClick, filterOtherRecordsCollection, + currentText, + otherText, } = props; const { insert, setVisible } = useSchemaInitializer(); const compile = useCompile(); @@ -358,6 +364,8 @@ export const DataBlockInitializer = (props: DataBlockInitializerProps) => { dataBlockInitializerProps: props, hideOtherRecordsInPopup, onClick, + currentText, + otherText, }); const getMenuItems = useGetSchemaInitializerMenuItems(onClick); const childItems = useMemo(() => { diff --git a/packages/core/client/src/schema-initializer/items/DeleteEventActionInitializer.tsx b/packages/core/client/src/schema-initializer/items/DeleteEventActionInitializer.tsx index 4a750b71a6..31f63a8d40 100644 --- a/packages/core/client/src/schema-initializer/items/DeleteEventActionInitializer.tsx +++ b/packages/core/client/src/schema-initializer/items/DeleteEventActionInitializer.tsx @@ -8,8 +8,7 @@ */ import React from 'react'; - -import { ActionInitializer } from './ActionInitializer'; +import { ActionInitializerItem } from './ActionInitializerItem'; export const DeleteEventActionInitializer = (props) => { const schema = { @@ -26,5 +25,5 @@ export const DeleteEventActionInitializer = (props) => { }, }, }; - return ; + return ; }; diff --git a/packages/core/client/src/schema-initializer/items/SelectActionInitializer.tsx b/packages/core/client/src/schema-initializer/items/SelectActionInitializer.tsx index 54c31b8298..74edf63a8c 100644 --- a/packages/core/client/src/schema-initializer/items/SelectActionInitializer.tsx +++ b/packages/core/client/src/schema-initializer/items/SelectActionInitializer.tsx @@ -8,7 +8,7 @@ */ import React from 'react'; -import { ActionInitializer } from './ActionInitializer'; +import { ActionInitializerItem } from './ActionInitializerItem'; export const SelectActionInitializer = (props) => { const schema = { @@ -65,5 +65,5 @@ export const SelectActionInitializer = (props) => { }, }, }; - return ; + return ; }; diff --git a/packages/core/client/src/schema-initializer/items/SubmitActionInitializer.tsx b/packages/core/client/src/schema-initializer/items/SubmitActionInitializer.tsx index dc760fbbad..c32a100586 100644 --- a/packages/core/client/src/schema-initializer/items/SubmitActionInitializer.tsx +++ b/packages/core/client/src/schema-initializer/items/SubmitActionInitializer.tsx @@ -8,8 +8,7 @@ */ import React from 'react'; - -import { ActionInitializer } from './ActionInitializer'; +import { ActionInitializerItem } from './ActionInitializerItem'; export const SubmitActionInitializer = (props) => { const schema = { @@ -24,5 +23,5 @@ export const SubmitActionInitializer = (props) => { htmlType: 'submit', }, }; - return ; + return ; }; diff --git a/packages/core/client/src/schema-initializer/items/index.tsx b/packages/core/client/src/schema-initializer/items/index.tsx index 4b379133bf..4f8bf80b91 100644 --- a/packages/core/client/src/schema-initializer/items/index.tsx +++ b/packages/core/client/src/schema-initializer/items/index.tsx @@ -13,6 +13,7 @@ export * from '../../schema-component/antd/association-filter/AssociationFilter' export * from '../../schema-component/antd/association-filter/AssociationFilterDesignerDelete'; export * from '../../schema-component/antd/association-filter/AssociationFilterDesignerDisplayField'; export * from './ActionInitializer'; +export * from './ActionInitializerItem'; export * from './BlockInitializer'; export * from './CreateFilterActionInitializer'; export * from './CreateResetActionInitializer'; diff --git a/packages/core/client/src/schema-initializer/utils.ts b/packages/core/client/src/schema-initializer/utils.ts index b29a399826..756a1483a4 100644 --- a/packages/core/client/src/schema-initializer/utils.ts +++ b/packages/core/client/src/schema-initializer/utils.ts @@ -857,6 +857,8 @@ export const useCollectionDataSourceItems = ({ hideOtherRecordsInPopup, onClick, filterOtherRecordsCollection, + currentText, + otherText, }: { componentName; filter?: (options: { collection?: Collection; associationField?: CollectionFieldOptions }) => boolean; @@ -873,6 +875,8 @@ export const useCollectionDataSourceItems = ({ * 用来筛选弹窗中的 “Other records” 选项中的数据表 */ filterOtherRecordsCollection?: (collection: Collection) => boolean; + currentText?: string; + otherText?: string; }) => { const { t } = useTranslation(); const dm = useDataSourceManager(); @@ -932,7 +936,7 @@ export const useCollectionDataSourceItems = ({ componentProps: { ...dataBlockInitializerProps, icon: null, - title: t('Current record'), + title: currentText || t('Current record'), name: 'currentRecord', hideSearch: false, hideChildrenIfSingleCollection: true, @@ -970,7 +974,7 @@ export const useCollectionDataSourceItems = ({ onClick() {}, componentProps: { icon: null, - title: t('Other records'), + title: otherText || t('Other records'), name: 'otherRecords', showAssociationFields: false, onlyCurrentDataSource: false, @@ -1031,6 +1035,7 @@ export const useCollectionDataSourceItems = ({ collection.name, componentName, dataBlockInitializerProps, + filterOtherRecordsCollection, hideOtherRecordsInPopup, noAssociationMenu, onClick, diff --git a/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditBlockInitializers.tsx b/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditBlockInitializers.tsx index 939606f537..a50ac823cb 100644 --- a/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditBlockInitializers.tsx +++ b/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditBlockInitializers.tsx @@ -47,12 +47,7 @@ export const CreateFormBulkEditBlockInitializers: SchemaInitializer = new Schema ], }); -/** - * @deprecated - * use `bulkEditBlockInitializers` instead - */ -export const BulkEditBlockInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'BulkEditBlockInitializers', +const commonOptions = { wrap: gridRowColWrap, title: '{{t("Add block")}}', icon: 'PlusOutlined', @@ -82,40 +77,21 @@ export const BulkEditBlockInitializers_deprecated = new CompatibleSchemaInitiali ], }, ], +}; + +/** + * @deprecated + * use `bulkEditBlockInitializers` instead + */ +export const BulkEditBlockInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'BulkEditBlockInitializers', + ...commonOptions, }); export const bulkEditBlockInitializers = new CompatibleSchemaInitializer( { name: 'popup:bulkEdit:addBlock', - wrap: gridRowColWrap, - title: '{{t("Add block")}}', - icon: 'PlusOutlined', - items: [ - { - type: 'itemGroup', - title: '{{t("Data blocks")}}', - name: 'dataBlocks', - children: [ - { - name: 'form', - title: '{{t("Form")}}', - Component: CreateFormBulkEditBlockInitializer, - }, - ], - }, - { - type: 'itemGroup', - title: '{{t("Other blocks")}}', - name: 'otherBlocks', - children: [ - { - name: 'markdown', - title: '{{t("Markdown")}}', - Component: 'MarkdownBlockInitializer', - }, - ], - }, - ], + ...commonOptions, }, BulkEditBlockInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditFormActionInitializers.tsx b/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditFormActionInitializers.tsx index 0a29f8bb84..d8e9c1c8f5 100644 --- a/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditFormActionInitializers.tsx +++ b/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditFormActionInitializers.tsx @@ -10,12 +10,7 @@ import { CompatibleSchemaInitializer } from '@nocobase/client'; import { BulkEditSubmitActionInitializer } from './BulkEditSubmitActionInitializer'; -/** - * @deprecated - * use `bulkEditFormActionInitializers` instead - */ -export const BulkEditFormActionInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'BulkEditFormActionInitializers', +const commonOptions = { title: '{{t("Configure actions")}}', icon: 'SettingOutlined', items: [ @@ -35,30 +30,21 @@ export const BulkEditFormActionInitializers_deprecated = new CompatibleSchemaIni ], }, ], +}; + +/** + * @deprecated + * use `bulkEditFormActionInitializers` instead + */ +export const BulkEditFormActionInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'BulkEditFormActionInitializers', + ...commonOptions, }); export const bulkEditFormActionInitializers = new CompatibleSchemaInitializer( { name: 'bulkEditForm:configureActions', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - items: [ - { - type: 'itemGroup', - title: '{{t("Enable actions")}}', - name: 'enableActions', - children: [ - { - name: 'submit', - title: '{{t("Submit")}}', - Component: BulkEditSubmitActionInitializer, - schema: { - 'x-action-settings': {}, - }, - }, - ], - }, - ], + ...commonOptions, }, BulkEditFormActionInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditFormItemInitializers.tsx b/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditFormItemInitializers.tsx index 92b5508e3e..1e609eeec8 100644 --- a/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditFormItemInitializers.tsx +++ b/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditFormItemInitializers.tsx @@ -10,12 +10,7 @@ import { CompatibleSchemaInitializer, gridRowColWrap } from '@nocobase/client'; import { useCustomBulkEditFormItemInitializerFields } from './utils'; -/** - * @deprecated - * use `bulkEditFormItemInitializers` instead - */ -export const BulkEditFormItemInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'BulkEditFormItemInitializers', +const commonOptions = { wrap: gridRowColWrap, icon: 'SettingOutlined', title: '{{t("Configure fields")}}', @@ -48,43 +43,21 @@ export const BulkEditFormItemInitializers_deprecated = new CompatibleSchemaIniti }, }, ], +}; + +/** + * @deprecated + * use `bulkEditFormItemInitializers` instead + */ +export const BulkEditFormItemInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'BulkEditFormItemInitializers', + ...commonOptions, }); export const bulkEditFormItemInitializers = new CompatibleSchemaInitializer( { name: 'bulkEditForm:configureFields', - wrap: gridRowColWrap, - icon: 'SettingOutlined', - title: '{{t("Configure fields")}}', - items: [ - { - name: 'displayFields', - type: 'itemGroup', - title: '{{t("Display fields")}}', - useChildren: useCustomBulkEditFormItemInitializerFields, - }, - { - name: 'divider', - type: 'divider', - }, - { - name: 'addText', - title: '{{t("Add text")}}', - Component: 'BlockItemInitializer', - schema: { - type: 'void', - 'x-editable': false, - 'x-decorator': 'FormItem', - // 'x-designer': 'Markdown.Void.Designer', - 'x-toolbar': 'FormItemSchemaToolbar', - 'x-settings': 'blockSettings:markdown', - 'x-component': 'Markdown.Void', - 'x-component-props': { - content: '{{t("This is a demo text, **supports Markdown syntax**.")}}', - }, - }, - }, - ], + ...commonOptions, }, BulkEditFormItemInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditSubmitActionInitializer.tsx b/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditSubmitActionInitializer.tsx index 6bfdab8cb1..4cf62b04b8 100644 --- a/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditSubmitActionInitializer.tsx +++ b/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/BulkEditSubmitActionInitializer.tsx @@ -7,8 +7,8 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ +import { ActionInitializerItem } from '@nocobase/client'; import React from 'react'; -import { ActionInitializer } from '@nocobase/client'; export const BulkEditSubmitActionInitializer = (props) => { const schema = { @@ -24,5 +24,5 @@ export const BulkEditSubmitActionInitializer = (props) => { htmlType: 'submit', }, }; - return ; + return ; }; diff --git a/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/__e2e__/schemaInitailizer.test.ts b/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/__e2e__/schemaInitailizer.test.ts index 6feeea9eb7..ce18c1ca0d 100644 --- a/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/__e2e__/schemaInitailizer.test.ts +++ b/packages/plugins/@nocobase/plugin-action-bulk-edit/src/client/__e2e__/schemaInitailizer.test.ts @@ -14,7 +14,6 @@ test.describe('TableActionInitializers & GanttActionInitializers & MapActionInit test('bulk edit in TableActionInitializers', async ({ page, mockPage }) => { await mockPage(oneEmptyTableBlockWithActions).goto(); await page.getByLabel('schema-initializer-ActionBar-table:configureActions-general').hover(); - await page.getByRole('menuitem', { name: 'Customize right' }).click(); await page.getByRole('menuitem', { name: 'Bulk edit' }).click(); await page.mouse.move(300, 0); await expect(page.getByLabel('Bulk edit')).toBeVisible(); @@ -24,7 +23,6 @@ test.describe('TableActionInitializers & GanttActionInitializers & MapActionInit await mockRecords('general', 3); await nocoPage.goto(); await page.getByLabel('schema-initializer-ActionBar-gantt:configureActions-general').hover(); - await page.getByRole('menuitem', { name: 'Customize right' }).click(); await page.getByRole('menuitem', { name: 'Bulk edit' }).click(); await expect(page.getByLabel('Bulk edit')).toBeVisible(); }); diff --git a/packages/plugins/@nocobase/plugin-action-bulk-update/src/client/__e2e__/schemaInitailizer.test.ts b/packages/plugins/@nocobase/plugin-action-bulk-update/src/client/__e2e__/schemaInitailizer.test.ts index 494f021392..eb0a298ce5 100644 --- a/packages/plugins/@nocobase/plugin-action-bulk-update/src/client/__e2e__/schemaInitailizer.test.ts +++ b/packages/plugins/@nocobase/plugin-action-bulk-update/src/client/__e2e__/schemaInitailizer.test.ts @@ -14,7 +14,6 @@ test.describe('TableActionInitializers & GanttActionInitializers & MapActionInit test('TableActionInitializers should add bulk update', async ({ page, mockPage }) => { await mockPage(oneEmptyTableBlockWithCustomizeActions).goto(); await page.getByLabel('schema-initializer-ActionBar-table:configureActions-general').hover(); - await page.getByRole('menuitem', { name: 'Customize right' }).click(); await page.getByRole('menuitem', { name: 'Bulk update' }).click(); await expect(page.getByLabel('action-Action-Bulk update-customize:bulkUpdate-general-table')).toBeVisible(); }); @@ -23,7 +22,6 @@ test.describe('TableActionInitializers & GanttActionInitializers & MapActionInit await mockRecords('general', 3); await nocoPage.goto(); await page.getByLabel('schema-initializer-ActionBar-gantt:configureActions-general').hover(); - await page.getByRole('menuitem', { name: 'Customize right' }).click(); await page.getByRole('menuitem', { name: 'Bulk update' }).click(); await page.mouse.move(300, 0); await expect(page.getByRole('button', { name: 'Bulk update' })).toBeVisible(); diff --git a/packages/plugins/@nocobase/plugin-action-custom-request/src/client/__e2e__/schemaSettings.test.ts b/packages/plugins/@nocobase/plugin-action-custom-request/src/client/__e2e__/schemaSettings.test.ts index d2a81490f1..eadc0d51f9 100644 --- a/packages/plugins/@nocobase/plugin-action-custom-request/src/client/__e2e__/schemaSettings.test.ts +++ b/packages/plugins/@nocobase/plugin-action-custom-request/src/client/__e2e__/schemaSettings.test.ts @@ -18,7 +18,6 @@ test.describe('custom request action', () => { // 新建一个 custom request action await page.getByRole('button', { name: 'Actions', exact: true }).hover(); await page.getByLabel('designer-schema-settings-TableV2.Column-TableV2.ActionColumnDesigner-').hover(); - await page.getByRole('menuitem', { name: 'Customize right' }).hover(); await page.getByRole('menuitem', { name: 'Custom request' }).click(); // 打开编辑按钮弹窗 @@ -37,7 +36,6 @@ test.describe('custom request action', () => { // 1. 新建一个 custom request action await page.getByLabel('schema-initializer-ActionBar-').hover(); - await page.getByRole('menuitem', { name: 'Customize' }).hover(); await page.getByRole('menuitem', { name: 'Custom request' }).click(); // 2. 打开编辑按钮弹窗 diff --git a/packages/plugins/@nocobase/plugin-action-duplicate/src/client/DuplicateActionInitializer.tsx b/packages/plugins/@nocobase/plugin-action-duplicate/src/client/DuplicateActionInitializer.tsx index e9073844e0..ac5bc3794c 100644 --- a/packages/plugins/@nocobase/plugin-action-duplicate/src/client/DuplicateActionInitializer.tsx +++ b/packages/plugins/@nocobase/plugin-action-duplicate/src/client/DuplicateActionInitializer.tsx @@ -7,7 +7,7 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { ActionInitializer } from '@nocobase/client'; +import { ActionInitializerItem } from '@nocobase/client'; import React from 'react'; export const DuplicateActionInitializer = (props) => { @@ -58,5 +58,5 @@ export const DuplicateActionInitializer = (props) => { }, }, }; - return ; + return ; }; diff --git a/packages/plugins/@nocobase/plugin-action-duplicate/src/client/__e2e__/schemaSettings.test.ts b/packages/plugins/@nocobase/plugin-action-duplicate/src/client/__e2e__/schemaSettings.test.ts index d38e516e54..bd9d3e3fc0 100644 --- a/packages/plugins/@nocobase/plugin-action-duplicate/src/client/__e2e__/schemaSettings.test.ts +++ b/packages/plugins/@nocobase/plugin-action-duplicate/src/client/__e2e__/schemaSettings.test.ts @@ -45,7 +45,8 @@ test.describe('direct duplicate & copy into the form and continue to fill in', ( await page.getByLabel('action-Action.Link-Duplicate-duplicate-general-table-0').click(); await page.getByLabel('schema-initializer-Grid-popup:addNew:addBlock-general').hover(); //配置表单区块 - await page.getByRole('menuitem', { name: 'form Form' }).click(); + await page.getByRole('menuitem', { name: 'form Form' }).hover(); + await page.getByRole('menuitem', { name: 'Current collection' }).click(); await page.mouse.move(300, 0); await page.getByLabel('schema-initializer-Grid-form:configureFields-general').hover(); await page.getByRole('menuitem', { name: 'singleLineText' }).click(); diff --git a/packages/plugins/@nocobase/plugin-action-export/src/client/ExportActionInitializer.tsx b/packages/plugins/@nocobase/plugin-action-export/src/client/ExportActionInitializer.tsx index 32af314506..18e90adb92 100644 --- a/packages/plugins/@nocobase/plugin-action-export/src/client/ExportActionInitializer.tsx +++ b/packages/plugins/@nocobase/plugin-action-export/src/client/ExportActionInitializer.tsx @@ -7,12 +7,11 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { Schema, useFieldSchema } from '@formily/react'; +import { Schema } from '@formily/react'; import { merge } from '@formily/shared'; import { - SchemaInitializerSwitch, + SchemaInitializerItem, useCollection_deprecated, - useDesignable, useSchemaInitializer, useSchemaInitializerItem, } from '@nocobase/client'; @@ -31,21 +30,6 @@ const findSchema = (schema: Schema, key: string, action: string) => { return buf; }); }; -const removeSchema = (schema, cb) => { - return cb(schema); -}; -export const useCurrentSchema = (action: string, key: string, find = findSchema, rm = removeSchema) => { - const fieldSchema = useFieldSchema(); - const { remove } = useDesignable(); - const schema = find(fieldSchema, key, action); - return { - schema, - exists: !!schema, - remove() { - schema && rm(schema, remove); - }, - }; -}; const initExportSettings = (fields) => { const exportSettings = fields?.filter((f) => !f.children).map((f) => ({ dataIndex: [f.name] })); @@ -55,7 +39,6 @@ const initExportSettings = (fields) => { export const ExportActionInitializer = () => { const itemConfig = useSchemaInitializerItem(); const { insert } = useSchemaInitializer(); - const { exists, remove } = useCurrentSchema('export', 'x-action', itemConfig.find, itemConfig.remove); const { name } = useCollection_deprecated(); const fields = useFields(name); @@ -75,15 +58,11 @@ export const ExportActionInitializer = () => { icon: 'clouddownloadoutlined', }, }; + return ( - { - if (exists) { - return remove(); - } schema['x-action-settings']['exportSettings'] = initExportSettings(fields); const s = merge(schema || {}, itemConfig.schema || {}); itemConfig?.schemaInitialize?.(s); diff --git a/packages/plugins/@nocobase/plugin-action-import/src/client/ImportActionInitializer.tsx b/packages/plugins/@nocobase/plugin-action-import/src/client/ImportActionInitializer.tsx index 71780a35aa..faf6c8ea95 100644 --- a/packages/plugins/@nocobase/plugin-action-import/src/client/ImportActionInitializer.tsx +++ b/packages/plugins/@nocobase/plugin-action-import/src/client/ImportActionInitializer.tsx @@ -8,21 +8,20 @@ */ import type { ISchema } from '@formily/react'; -import { Schema, useFieldSchema } from '@formily/react'; +import { Schema } from '@formily/react'; import { merge } from '@formily/shared'; import { - SchemaInitializerSwitch, + SchemaInitializerItem, css, useCollection_deprecated, - useDesignable, useSchemaInitializer, useSchemaInitializerItem, } from '@nocobase/client'; +import { Alert } from 'antd'; import React from 'react'; import { NAMESPACE } from './constants'; -import { useFields } from './useFields'; -import { Alert } from 'antd'; import { useImportTranslation } from './locale'; +import { useFields } from './useFields'; const findSchema = (schema: Schema, key: string, action: string) => { return schema.reduceProperties((buf, s) => { @@ -36,21 +35,6 @@ const findSchema = (schema: Schema, key: string, action: string) => { return buf; }); }; -const removeSchema = (schema, cb) => { - return cb(schema); -}; -export const useCurrentSchema = (action: string, key: string, find = findSchema, rm = removeSchema) => { - const fieldSchema = useFieldSchema(); - const { remove } = useDesignable(); - const schema = find(fieldSchema, key, action); - return { - schema, - exists: !!schema, - remove() { - schema && rm(schema, remove); - }, - }; -}; const initImportSettings = (fields) => { const importColumns = fields?.filter((f) => !f.children).map((f) => ({ dataIndex: [f.name] })); @@ -65,7 +49,6 @@ export const ImportWarning = () => { export const ImportActionInitializer = () => { const itemConfig = useSchemaInitializerItem(); const { insert } = useSchemaInitializer(); - const { exists, remove } = useCurrentSchema('importXlsx', 'x-action', itemConfig.find, itemConfig.remove); const { name } = useCollection_deprecated(); const fields = useFields(name); const schema: ISchema = { @@ -196,15 +179,11 @@ export const ImportActionInitializer = () => { }, }, }; + return ( - { - if (exists) { - return remove(); - } schema['x-action-settings']['importSettings'] = initImportSettings(fields); const s = merge(schema || {}, itemConfig.schema || {}); itemConfig?.schemaInitialize?.(s); diff --git a/packages/plugins/@nocobase/plugin-action-print/src/client/PrintActionInitializer.tsx b/packages/plugins/@nocobase/plugin-action-print/src/client/PrintActionInitializer.tsx index 13d6421a96..107cf142fd 100644 --- a/packages/plugins/@nocobase/plugin-action-print/src/client/PrintActionInitializer.tsx +++ b/packages/plugins/@nocobase/plugin-action-print/src/client/PrintActionInitializer.tsx @@ -7,9 +7,8 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import React from 'react'; - import { ActionInitializer } from '@nocobase/client'; +import React from 'react'; export const PrintActionInitializer = (props) => { const schema = { diff --git a/packages/plugins/@nocobase/plugin-audit-logs/src/client/components/AuditLogsViewActionInitializer.tsx b/packages/plugins/@nocobase/plugin-audit-logs/src/client/components/AuditLogsViewActionInitializer.tsx index 9f614ab978..832a11a706 100644 --- a/packages/plugins/@nocobase/plugin-audit-logs/src/client/components/AuditLogsViewActionInitializer.tsx +++ b/packages/plugins/@nocobase/plugin-audit-logs/src/client/components/AuditLogsViewActionInitializer.tsx @@ -7,7 +7,7 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { ActionInitializer } from '@nocobase/client'; +import { ActionInitializerItem } from '@nocobase/client'; import React from 'react'; export const AuditLogsViewActionInitializer = () => { @@ -346,5 +346,5 @@ export const AuditLogsViewActionInitializer = () => { }, }, }; - return ; + return ; }; diff --git a/packages/plugins/@nocobase/plugin-audit-logs/src/client/initializers/AuditLogsTableActionColumnInitializers.tsx b/packages/plugins/@nocobase/plugin-audit-logs/src/client/initializers/AuditLogsTableActionColumnInitializers.tsx index a554a48796..333d121433 100644 --- a/packages/plugins/@nocobase/plugin-audit-logs/src/client/initializers/AuditLogsTableActionColumnInitializers.tsx +++ b/packages/plugins/@nocobase/plugin-audit-logs/src/client/initializers/AuditLogsTableActionColumnInitializers.tsx @@ -19,12 +19,7 @@ import { import React from 'react'; import { useTranslation } from 'react-i18next'; -/** - * @deprecated - * use `auditLogsTableActionColumnInitializers` instead - */ -export const auditLogsTableActionColumnInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'AuditLogsTableActionColumnInitializers', +const commonOptions = { insertPosition: 'beforeEnd', Component: (props: any) => , useInsert() { @@ -83,69 +78,21 @@ export const auditLogsTableActionColumnInitializers_deprecated = new CompatibleS Component: Resizable, }, ], +}; + +/** + * @deprecated + * use `auditLogsTableActionColumnInitializers` instead + */ +export const auditLogsTableActionColumnInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'AuditLogsTableActionColumnInitializers', + ...commonOptions, }); export const auditLogsTableActionColumnInitializers = new CompatibleSchemaInitializer( { name: 'auditLogsTable:configureItemActions', - insertPosition: 'beforeEnd', - Component: (props: any) => , - useInsert() { - const fieldSchema = useFieldSchema(); - const api = useAPIClient(); - const { refresh } = useDesignable(); - const { t } = useTranslation(); - - return (schema) => { - const spaceSchema = fieldSchema.reduceProperties((buf, schema) => { - if (schema['x-component'] === 'Space') { - return schema; - } - return buf; - }, null); - if (!spaceSchema) { - return; - } - const dn = createDesignable({ - t, - api, - refresh, - current: spaceSchema, - }); - dn.loadAPIClientEvents(); - dn.insertBeforeEnd(schema); - }; - }, - items: [ - { - name: 'enableActions', - type: 'itemGroup', - title: '{{t("Enable actions")}}', - children: [ - { - name: 'view', - type: 'item', - title: '{{t("View")}}', - Component: 'AuditLogsViewActionInitializer', - schema: { - 'x-component': 'Action.Link', - 'x-action': 'view', - 'x-decorator': 'ACLActionProvider', - }, - }, - ], - }, - { - name: 'divider', - type: 'divider', - }, - { - name: 'columnWidth', - type: 'item', - title: '{{t("Column width")}}', - Component: Resizable, - }, - ], + ...commonOptions, }, auditLogsTableActionColumnInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-audit-logs/src/client/initializers/AuditLogsTableActionInitializers.tsx b/packages/plugins/@nocobase/plugin-audit-logs/src/client/initializers/AuditLogsTableActionInitializers.tsx index 5d39838ea4..0f700b4880 100644 --- a/packages/plugins/@nocobase/plugin-audit-logs/src/client/initializers/AuditLogsTableActionInitializers.tsx +++ b/packages/plugins/@nocobase/plugin-audit-logs/src/client/initializers/AuditLogsTableActionInitializers.tsx @@ -9,13 +9,7 @@ import { CompatibleSchemaInitializer } from '@nocobase/client'; -/** - * @deprecated - * use `auditLogsTableActionInitializers` instead - * 操作记录表格操作配置 - */ -export const auditLogsTableActionInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'AuditLogsTableActionInitializers', +const commonOptions = { title: "{{t('Configure actions')}}", icon: 'SettingOutlined', style: { @@ -46,41 +40,22 @@ export const auditLogsTableActionInitializers_deprecated = new CompatibleSchemaI ], }, ], +}; + +/** + * @deprecated + * use `auditLogsTableActionInitializers` instead + * 操作记录表格操作配置 + */ +export const auditLogsTableActionInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'AuditLogsTableActionInitializers', + ...commonOptions, }); export const auditLogsTableActionInitializers = new CompatibleSchemaInitializer( { name: 'auditLogsTable:configureActions', - title: "{{t('Configure actions')}}", - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'itemGroup', - title: "{{t('Enable actions')}}", - name: 'enableActions', - children: [ - { - name: 'filter', - title: "{{t('Filter')}}", - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'left', - }, - }, - { - name: 'refresh', - title: "{{t('Refresh')}}", - Component: 'RefreshActionInitializer', - schema: { - 'x-align': 'right', - }, - }, - ], - }, - ], + ...commonOptions, }, auditLogsTableActionInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-audit-logs/src/client/initializers/AuditLogsTableColumnInitializers.tsx b/packages/plugins/@nocobase/plugin-audit-logs/src/client/initializers/AuditLogsTableColumnInitializers.tsx index 5fc45001fa..118d46839b 100644 --- a/packages/plugins/@nocobase/plugin-audit-logs/src/client/initializers/AuditLogsTableColumnInitializers.tsx +++ b/packages/plugins/@nocobase/plugin-audit-logs/src/client/initializers/AuditLogsTableColumnInitializers.tsx @@ -53,12 +53,7 @@ const AssociatedFields = () => { return {schema}; }; -/** - * @deprecated - * use `auditLogsTableColumnInitializers` instead - */ -export const auditLogsTableColumnInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'AuditLogsTableColumnInitializers', +const commonOptions = { insertPosition: 'beforeEnd', icon: 'SettingOutlined', title: '{{t("Configure columns")}}', @@ -99,51 +94,21 @@ export const auditLogsTableColumnInitializers_deprecated = new CompatibleSchemaI Component: 'AuditLogsTableActionColumnInitializer', }, ], +}; + +/** + * @deprecated + * use `auditLogsTableColumnInitializers` instead + */ +export const auditLogsTableColumnInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'AuditLogsTableColumnInitializers', + ...commonOptions, }); export const auditLogsTableColumnInitializers = new CompatibleSchemaInitializer( { name: 'auditLogsTable:configureColumns', - insertPosition: 'beforeEnd', - icon: 'SettingOutlined', - title: '{{t("Configure columns")}}', - wrap(s) { - if (s['x-action-column']) { - return s; - } - return { - type: 'void', - 'x-decorator': 'TableV2.Column.Decorator', - 'x-designer': 'TableV2.Column.Designer', - 'x-component': 'TableV2.Column', - properties: { - [s.name]: { - ...s, - }, - }, - }; - }, - items: [ - { - name: 'displayFields', - type: 'itemGroup', - title: '{{t("Display fields")}}', - useChildren: useTableColumnInitializerFields, - }, - { - name: 'parentCollectionFields', - Component: ParentCollectionFields, - }, - { - name: 'associationFields', - Component: AssociatedFields, - }, - { - name: 'actionColumn', - title: '{{t("Action column")}}', - Component: 'AuditLogsTableActionColumnInitializer', - }, - ], + ...commonOptions, }, auditLogsTableColumnInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-calendar/src/client/schema-initializer/initializers/CalendarActionInitializers.tsx b/packages/plugins/@nocobase/plugin-calendar/src/client/schema-initializer/initializers/CalendarActionInitializers.tsx index a9e213dc34..6bd779ec11 100644 --- a/packages/plugins/@nocobase/plugin-calendar/src/client/schema-initializer/initializers/CalendarActionInitializers.tsx +++ b/packages/plugins/@nocobase/plugin-calendar/src/client/schema-initializer/initializers/CalendarActionInitializers.tsx @@ -7,183 +7,111 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { CompatibleSchemaInitializer, useCollection_deprecated } from '@nocobase/client'; +import { + CompatibleSchemaInitializer, + InitializerWithSwitch, + useCollection_deprecated, + useSchemaInitializerItem, +} from '@nocobase/client'; +import React from 'react'; import { generateNTemplate } from '../../../locale'; +const CalendarActionInitializer = (props) => { + const itemConfig = useSchemaInitializerItem(); + return ; +}; + +const commonOptions = { + title: generateNTemplate('Configure actions'), + icon: 'SettingOutlined', + style: { marginLeft: 8 }, + items: [ + { + name: 'today', + title: generateNTemplate('Today'), + Component: CalendarActionInitializer, + schema: { + title: generateNTemplate('Today'), + 'x-component': 'CalendarV2.Today', + 'x-action': `calendar:today`, + 'x-align': 'left', + }, + }, + { + name: 'turnPages', + title: generateNTemplate('Turn pages'), + Component: CalendarActionInitializer, + schema: { + title: generateNTemplate('Turn pages'), + 'x-component': 'CalendarV2.Nav', + 'x-action': `calendar:nav`, + 'x-align': 'left', + }, + }, + { + name: 'title', + title: generateNTemplate('Title'), + Component: CalendarActionInitializer, + schema: { + title: generateNTemplate('Title'), + 'x-component': 'CalendarV2.Title', + 'x-action': `calendar:title`, + 'x-align': 'left', + }, + }, + { + name: 'selectView', + title: generateNTemplate('Select view'), + Component: CalendarActionInitializer, + schema: { + title: generateNTemplate('Select view'), + 'x-component': 'CalendarV2.ViewSelect', + 'x-action': `calendar:viewSelect`, + 'x-align': 'right', + 'x-designer': 'Action.Designer', + }, + }, + { + name: 'filter', + title: generateNTemplate('Filter'), + Component: 'FilterActionInitializer', + schema: { + 'x-align': 'right', + }, + }, + { + name: 'addNew', + title: generateNTemplate('Add new'), + Component: 'CreateActionInitializer', + schema: { + 'x-align': 'right', + 'x-decorator': 'ACLActionProvider', + 'x-acl-action-props': { + skipScopeCheck: true, + }, + }, + useVisible() { + const collection = useCollection_deprecated(); + return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; + }, + }, + ], +}; + /** * @deprecated * use `calendarActionInitializers` instead * 日历的操作配置 */ export const CalendarActionInitializers_deprecated = new CompatibleSchemaInitializer({ - title: generateNTemplate('Configure actions'), - icon: 'SettingOutlined', name: 'CalendarActionInitializers', - style: { marginLeft: 8 }, - items: [ - { - type: 'itemGroup', - name: 'enableActions', - title: generateNTemplate('Enable actions'), - children: [ - { - name: 'today', - title: generateNTemplate('Today'), - Component: 'ActionInitializer', - schema: { - title: generateNTemplate('Today'), - 'x-component': 'CalendarV2.Today', - 'x-action': `calendar:today`, - 'x-align': 'left', - }, - }, - { - name: 'turnPages', - title: generateNTemplate('Turn pages'), - Component: 'ActionInitializer', - schema: { - title: generateNTemplate('Turn pages'), - 'x-component': 'CalendarV2.Nav', - 'x-action': `calendar:nav`, - 'x-align': 'left', - }, - }, - { - name: 'title', - title: generateNTemplate('Title'), - Component: 'ActionInitializer', - schema: { - title: generateNTemplate('Title'), - 'x-component': 'CalendarV2.Title', - 'x-action': `calendar:title`, - 'x-align': 'left', - }, - }, - { - name: 'selectView', - title: generateNTemplate('Select view'), - Component: 'ActionInitializer', - schema: { - title: generateNTemplate('Select view'), - 'x-component': 'CalendarV2.ViewSelect', - 'x-action': `calendar:viewSelect`, - 'x-align': 'right', - 'x-designer': 'Action.Designer', - }, - }, - { - name: 'filter', - title: generateNTemplate('Filter'), - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'right', - }, - }, - { - name: 'addNew', - title: generateNTemplate('Add new'), - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - ], - }, - ], + ...commonOptions, }); export const calendarActionInitializers = new CompatibleSchemaInitializer( { - title: generateNTemplate('Configure actions'), - icon: 'SettingOutlined', name: 'calendar:configureActions', - style: { marginLeft: 8 }, - items: [ - { - type: 'itemGroup', - name: 'enableActions', - title: generateNTemplate('Enable actions'), - children: [ - { - name: 'today', - title: generateNTemplate('Today'), - Component: 'ActionInitializer', - schema: { - title: generateNTemplate('Today'), - 'x-component': 'CalendarV2.Today', - 'x-action': `calendar:today`, - 'x-align': 'left', - }, - }, - { - name: 'turnPages', - title: generateNTemplate('Turn pages'), - Component: 'ActionInitializer', - schema: { - title: generateNTemplate('Turn pages'), - 'x-component': 'CalendarV2.Nav', - 'x-action': `calendar:nav`, - 'x-align': 'left', - }, - }, - { - name: 'title', - title: generateNTemplate('Title'), - Component: 'ActionInitializer', - schema: { - title: generateNTemplate('Title'), - 'x-component': 'CalendarV2.Title', - 'x-action': `calendar:title`, - 'x-align': 'left', - }, - }, - { - name: 'selectView', - title: generateNTemplate('Select view'), - Component: 'ActionInitializer', - schema: { - title: generateNTemplate('Select view'), - 'x-component': 'CalendarV2.ViewSelect', - 'x-action': `calendar:viewSelect`, - 'x-align': 'right', - 'x-designer': 'Action.Designer', - }, - }, - { - name: 'filter', - title: generateNTemplate('Filter'), - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'right', - }, - }, - { - name: 'addNew', - title: generateNTemplate('Add new'), - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection.template !== 'view' || collection?.writableView) && collection.template !== 'sql'; - }, - }, - ], - }, - ], + ...commonOptions, }, CalendarActionInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-data-visualization/src/client/block/ChartBlockInitializer.tsx b/packages/plugins/@nocobase/plugin-data-visualization/src/client/block/ChartBlockInitializer.tsx index bd9e82be06..a0b6239cd7 100644 --- a/packages/plugins/@nocobase/plugin-data-visualization/src/client/block/ChartBlockInitializer.tsx +++ b/packages/plugins/@nocobase/plugin-data-visualization/src/client/block/ChartBlockInitializer.tsx @@ -59,12 +59,7 @@ const ChartInitializer = () => { ); }; -/** - * @deprecated - * use `chartInitializers` instead - */ -export const chartInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'ChartInitializers', +const commonOptions = { icon: 'PlusOutlined', title: '{{t("Add block")}}', items: [ @@ -86,32 +81,21 @@ export const chartInitializers_deprecated = new CompatibleSchemaInitializer({ ], }, ], +}; + +/** + * @deprecated + * use `chartInitializers` instead + */ +export const chartInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'ChartInitializers', + ...commonOptions, }); export const chartInitializers = new CompatibleSchemaInitializer( { name: 'charts:addBlock', - icon: 'PlusOutlined', - title: '{{t("Add block")}}', - items: [ - { - name: 'chart', - title: lang('Chart'), - Component: ChartInitializer, - }, - { - name: 'otherBlocks', - type: 'itemGroup', - title: lang('Other blocks'), - children: [ - { - name: 'filter', - title: lang('Filter'), - Component: FilterBlockInitializer, - }, - ], - }, - ], + ...commonOptions, }, chartInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-data-visualization/src/client/filter/FilterActionInitializers.tsx b/packages/plugins/@nocobase/plugin-data-visualization/src/client/filter/FilterActionInitializers.tsx index d7b034752c..b6ce74f4ef 100644 --- a/packages/plugins/@nocobase/plugin-data-visualization/src/client/filter/FilterActionInitializers.tsx +++ b/packages/plugins/@nocobase/plugin-data-visualization/src/client/filter/FilterActionInitializers.tsx @@ -132,95 +132,54 @@ const ChartFilterCollapseInitializer = (props) => { return ; }; +const commonOptions = { + 'data-testid': 'configure-actions-button-of-chart-filter', + title: '{{t("Configure actions")}}', + icon: 'SettingOutlined', + items: [ + { + name: 'filter', + type: 'item', + title: '{{t("Filter")}}', + component: ChartFilterActionInitializer, + schema: { + 'x-action-settings': {}, + }, + }, + { + name: 'reset', + type: 'item', + title: '{{t("Reset")}}', + component: ChartFilterResetInitializer, + schema: { + 'x-action-settings': {}, + }, + }, + { + name: 'collapse', + type: 'item', + title: '{{t("Collapse")}}', + component: ChartFilterCollapseInitializer, + schema: { + 'x-action-settings': {}, + }, + }, + ], +}; + /** * @deprecated * use `chartFilterActionInitializers` instead */ export const chartFilterActionInitializers_deprecated = new CompatibleSchemaInitializer({ name: 'ChartFilterActionInitializers', - 'data-testid': 'configure-actions-button-of-chart-filter', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - items: [ - { - name: 'enbaleActions', - type: 'itemGroup', - title: '{{t("Enable actions")}}', - children: [ - { - name: 'filter', - type: 'item', - title: '{{t("Filter")}}', - component: ChartFilterActionInitializer, - schema: { - 'x-action-settings': {}, - }, - }, - { - name: 'reset', - type: 'item', - title: '{{t("Reset")}}', - component: ChartFilterResetInitializer, - schema: { - 'x-action-settings': {}, - }, - }, - { - name: 'collapse', - type: 'item', - title: '{{t("Collapse")}}', - component: ChartFilterCollapseInitializer, - schema: { - 'x-action-settings': {}, - }, - }, - ], - }, - ], + ...commonOptions, }); export const chartFilterActionInitializers = new CompatibleSchemaInitializer( { name: 'chartFilterForm:configureActions', - 'data-testid': 'configure-actions-button-of-chart-filter', - title: '{{t("Configure actions")}}', - icon: 'SettingOutlined', - items: [ - { - name: 'enbaleActions', - type: 'itemGroup', - title: '{{t("Enable actions")}}', - children: [ - { - name: 'filter', - type: 'item', - title: '{{t("Filter")}}', - component: ChartFilterActionInitializer, - schema: { - 'x-action-settings': {}, - }, - }, - { - name: 'reset', - type: 'item', - title: '{{t("Reset")}}', - component: ChartFilterResetInitializer, - schema: { - 'x-action-settings': {}, - }, - }, - { - name: 'collapse', - type: 'item', - title: '{{t("Collapse")}}', - component: ChartFilterCollapseInitializer, - schema: { - 'x-action-settings': {}, - }, - }, - ], - }, - ], + ...commonOptions, }, chartFilterActionInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-file-manager/src/client/initializers/UploadActionInitializer.tsx b/packages/plugins/@nocobase/plugin-file-manager/src/client/initializers/UploadActionInitializer.tsx index 9aafd63ff7..7b20c7e2d5 100644 --- a/packages/plugins/@nocobase/plugin-file-manager/src/client/initializers/UploadActionInitializer.tsx +++ b/packages/plugins/@nocobase/plugin-file-manager/src/client/initializers/UploadActionInitializer.tsx @@ -7,7 +7,7 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { ActionInitializer, useCollection_deprecated } from '@nocobase/client'; +import { ActionInitializerItem, useCollection_deprecated } from '@nocobase/client'; import React from 'react'; export const UploadActionInitializer = (props) => { @@ -46,5 +46,5 @@ export const UploadActionInitializer = (props) => { }, }, }; - return ; + return ; }; diff --git a/packages/plugins/@nocobase/plugin-gantt/src/client/GanttActionInitializers.tsx b/packages/plugins/@nocobase/plugin-gantt/src/client/GanttActionInitializers.tsx index 60778f5d51..307209f044 100644 --- a/packages/plugins/@nocobase/plugin-gantt/src/client/GanttActionInitializers.tsx +++ b/packages/plugins/@nocobase/plugin-gantt/src/client/GanttActionInitializers.tsx @@ -10,12 +10,7 @@ import { useFieldSchema } from '@formily/react'; import { CompatibleSchemaInitializer, useCollection_deprecated } from '@nocobase/client'; -/** - * @deprecated - * use `ganttActionInitializers` instead - */ -export const GanttActionInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'GanttActionInitializers', +const commonOptions = { title: "{{t('Configure actions')}}", icon: 'SettingOutlined', style: { @@ -23,224 +18,84 @@ export const GanttActionInitializers_deprecated = new CompatibleSchemaInitialize }, items: [ { - type: 'itemGroup', - name: 'enableActions', - title: "{{t('Enable actions')}}", - children: [ - { - type: 'item', - name: 'filter', - title: "{{t('Filter')}}", - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'left', - }, - }, - { - type: 'item', - title: "{{t('Add new')}}", - name: 'addNew', - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'file', 'sql'].includes(collection.template) || collection?.writableView; - }, - }, - { - type: 'item', - title: "{{t('Delete')}}", - name: 'delete', - Component: 'BulkDestroyActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - }, - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'sql'].includes(collection.template) || collection?.writableView; - }, - }, - { - type: 'item', - title: "{{t('Refresh')}}", - name: 'refresh', - Component: 'RefreshActionInitializer', - schema: { - 'x-align': 'right', - }, - }, - { - name: 'toggle', - title: "{{t('Expand/Collapse')}}", - Component: 'ExpandableActionInitializer', - schema: { - 'x-align': 'right', - }, - useVisible() { - const schema = useFieldSchema(); - const collection = useCollection_deprecated(); - const { treeTable } = schema?.parent?.['x-decorator-props'] || {}; - return collection.tree && treeTable; - }, - }, - ], + type: 'item', + name: 'filter', + title: "{{t('Filter')}}", + Component: 'FilterActionInitializer', + schema: { + 'x-align': 'left', + }, }, { - name: 'divider', - type: 'divider', + type: 'item', + title: "{{t('Add new')}}", + name: 'addNew', + Component: 'CreateActionInitializer', + schema: { + 'x-align': 'right', + 'x-decorator': 'ACLActionProvider', + 'x-acl-action-props': { + skipScopeCheck: true, + }, + }, + useVisible() { + const collection = useCollection_deprecated(); + return !['view', 'file', 'sql'].includes(collection.template) || collection?.writableView; + }, + }, + { + type: 'item', + title: "{{t('Delete')}}", + name: 'delete', + Component: 'BulkDestroyActionInitializer', + schema: { + 'x-align': 'right', + 'x-decorator': 'ACLActionProvider', + }, useVisible() { const collection = useCollection_deprecated(); return !['view', 'sql'].includes(collection.template) || collection?.writableView; }, }, { - type: 'subMenu', - name: 'customize', - title: '{{t("Customize")}}', - children: [ - { - type: 'item', - title: '{{t("Add record")}}', - name: 'addRecord', - Component: 'CustomizeAddRecordActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action': 'create', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - }, - ], + type: 'item', + title: "{{t('Refresh')}}", + name: 'refresh', + Component: 'RefreshActionInitializer', + schema: { + 'x-align': 'right', + }, + }, + { + name: 'toggle', + title: "{{t('Expand/Collapse')}}", + Component: 'ExpandableActionInitializer', + schema: { + 'x-align': 'right', + }, useVisible() { + const schema = useFieldSchema(); const collection = useCollection_deprecated(); - return !['view', 'sql'].includes(collection.template) || collection?.writableView; + const { treeTable } = schema?.parent?.['x-decorator-props'] || {}; + return collection.tree && treeTable; }, }, ], +}; + +/** + * @deprecated + * use `ganttActionInitializers` instead + */ +export const GanttActionInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'GanttActionInitializers', + ...commonOptions, }); export const ganttActionInitializers = new CompatibleSchemaInitializer( { name: 'gantt:configureActions', - title: "{{t('Configure actions')}}", - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'itemGroup', - name: 'enableActions', - title: "{{t('Enable actions')}}", - children: [ - { - type: 'item', - name: 'filter', - title: "{{t('Filter')}}", - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'left', - }, - }, - { - type: 'item', - title: "{{t('Add new')}}", - name: 'addNew', - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'file', 'sql'].includes(collection.template) || collection?.writableView; - }, - }, - { - type: 'item', - title: "{{t('Delete')}}", - name: 'delete', - Component: 'BulkDestroyActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - }, - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'sql'].includes(collection.template) || collection?.writableView; - }, - }, - { - type: 'item', - title: "{{t('Refresh')}}", - name: 'refresh', - Component: 'RefreshActionInitializer', - schema: { - 'x-align': 'right', - }, - }, - { - name: 'toggle', - title: "{{t('Expand/Collapse')}}", - Component: 'ExpandableActionInitializer', - schema: { - 'x-align': 'right', - }, - useVisible() { - const schema = useFieldSchema(); - const collection = useCollection_deprecated(); - const { treeTable } = schema?.parent?.['x-decorator-props'] || {}; - return collection.tree && treeTable; - }, - }, - ], - }, - { - name: 'divider', - type: 'divider', - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'sql'].includes(collection.template) || collection?.writableView; - }, - }, - { - type: 'subMenu', - name: 'customize', - title: '{{t("Customize")}}', - children: [ - { - type: 'item', - title: '{{t("Add record")}}', - name: 'addRecord', - Component: 'CustomizeAddRecordActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action': 'create', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - }, - ], - useVisible() { - const collection = useCollection_deprecated(); - return !['view', 'sql'].includes(collection.template) || collection?.writableView; - }, - }, - ], + ...commonOptions, }, GanttActionInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-gantt/src/client/__e2e__/schemaInitailizer.test.ts b/packages/plugins/@nocobase/plugin-gantt/src/client/__e2e__/schemaInitailizer.test.ts index 914e12e332..412d2f3dfe 100644 --- a/packages/plugins/@nocobase/plugin-gantt/src/client/__e2e__/schemaInitailizer.test.ts +++ b/packages/plugins/@nocobase/plugin-gantt/src/client/__e2e__/schemaInitailizer.test.ts @@ -85,20 +85,17 @@ test.describe('configure actions', () => { test('configure button in gannt block', async ({ page, mockPage }) => { await mockPage(oneEmptyGantt).goto(); await page.getByLabel('schema-initializer-ActionBar-gantt:configureActions-general').hover(); - await page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch').click(); + await page.getByRole('menuitem', { name: 'Filter' }).click(); await page.getByRole('menuitem', { name: 'Add new' }).click(); await page.getByRole('menuitem', { name: 'Delete' }).click(); await page.getByRole('menuitem', { name: 'Refresh' }).click(); - await page.getByRole('menuitem', { name: 'Customize right' }).hover(); await page.getByRole('menuitem', { name: 'Bulk update' }).click(); await page.getByRole('menuitem', { name: 'Bulk edit' }).click(); - await page.getByRole('menuitem', { name: 'Add record' }).click(); await expect(page.getByLabel('action-Filter.Action-Filter-filter-general-table')).toBeVisible(); await expect(page.getByLabel('action-Action-Add new-create-general-table')).toBeVisible(); await expect(page.getByLabel('action-Action-Delete-destroy-general-table')).toBeVisible(); await expect(page.getByLabel('action-Action-Refresh-refresh-general-table')).toBeVisible(); await expect(page.getByLabel('action-Action-Bulk update-customize:bulkUpdate-general-table')).toBeVisible(); await expect(page.getByLabel('action-Action-Bulk edit-customize:bulkEdit-general-table')).toBeVisible(); - await expect(page.getByLabel('action-Action-Add record-customize:create-general-table')).toBeVisible(); }); }); diff --git a/packages/plugins/@nocobase/plugin-kanban/src/client/Kanban.Card.Designer.tsx b/packages/plugins/@nocobase/plugin-kanban/src/client/Kanban.Card.Designer.tsx index 374bffcf99..d63b8c47b0 100644 --- a/packages/plugins/@nocobase/plugin-kanban/src/client/Kanban.Card.Designer.tsx +++ b/packages/plugins/@nocobase/plugin-kanban/src/client/Kanban.Card.Designer.tsx @@ -68,12 +68,7 @@ export const KanbanCardDesigner = () => { ); }; -/** - * @deprecated - * use `kanbanCardInitializers` instead - */ -export const kanbanCardInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'KanbanCardInitializers', +const commonOptions = { wrap: gridRowColWrap, useInsert() { const fieldSchema = useFieldSchema(); @@ -144,81 +139,21 @@ export const kanbanCardInitializers_deprecated = new CompatibleSchemaInitializer Component: SchemaInitializerOpenModeSchemaItems, }, ], +}; + +/** + * @deprecated + * use `kanbanCardInitializers` instead + */ +export const kanbanCardInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'KanbanCardInitializers', + ...commonOptions, }); export const kanbanCardInitializers = new CompatibleSchemaInitializer( { name: 'kanban:configureItemFields', - wrap: gridRowColWrap, - useInsert() { - const fieldSchema = useFieldSchema(); - const { t } = useTranslation(); - const api = useAPIClient(); - const { refresh } = useDesignable(); - - return (schema) => { - const gridSchema = fieldSchema.reduceProperties((buf, schema) => { - if (schema['x-component'] === 'Grid') { - return schema; - } - return buf; - }, null); - - if (!gridSchema) { - return; - } - - const dn = createDesignable({ - t, - api, - refresh, - current: gridSchema, - }); - dn.loadAPIClientEvents(); - dn.insertBeforeEnd(schema); - }; - }, - Component: (props: any) => { - const { getAriaLabel } = useGetAriaLabelOfDesigner(); - return ( - - ); - }, - items: [ - { - type: 'itemGroup', - title: '{{t("Display fields")}}', - name: 'displayFields', - useChildren: useFormItemInitializerFields, - }, - { - type: 'itemGroup', - divider: true, - title: '{{t("Display association fields")}}', - name: 'displayAssociationFields', - hideIfNoChildren: true, - useChildren() { - const associationFields = useAssociatedFormItemInitializerFields({ - readPretty: true, - block: 'Kanban', - }); - return associationFields; - }, - }, - { - name: 'divider', - type: 'divider', - }, - { - name: 'openMode', - Component: SchemaInitializerOpenModeSchemaItems, - }, - ], + ...commonOptions, }, kanbanCardInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-kanban/src/client/KanbanActionInitializers.tsx b/packages/plugins/@nocobase/plugin-kanban/src/client/KanbanActionInitializers.tsx index 22aa940314..b4d0cb6661 100644 --- a/packages/plugins/@nocobase/plugin-kanban/src/client/KanbanActionInitializers.tsx +++ b/packages/plugins/@nocobase/plugin-kanban/src/client/KanbanActionInitializers.tsx @@ -9,12 +9,8 @@ import { CompatibleSchemaInitializer, useCollection_deprecated } from '@nocobase/client'; -/** - * @deprecated - * use `kanbanActionInitializers` instead - */ -export const kanbanActionInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'KanbanActionInitializers', +const commonOptions = { + name: 'kanban:configureActions', title: "{{t('Configure actions')}}", icon: 'SettingOutlined', style: { @@ -22,80 +18,45 @@ export const kanbanActionInitializers_deprecated = new CompatibleSchemaInitializ }, items: [ { - type: 'itemGroup', - title: "{{t('Enable actions')}}", - name: 'enableActions', - children: [ - { - name: 'filter', - title: "{{t('Filter')}}", - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'left', - }, + name: 'filter', + title: "{{t('Filter')}}", + Component: 'FilterActionInitializer', + schema: { + 'x-align': 'left', + }, + }, + { + name: 'addNew', + title: "{{t('Add new')}}", + Component: 'CreateActionInitializer', + schema: { + 'x-align': 'right', + 'x-decorator': 'ACLActionProvider', + 'x-acl-action-props': { + skipScopeCheck: true, }, - { - name: 'addNew', - title: "{{t('Add new')}}", - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection as any).template !== 'view' || collection?.writableView; - }, - }, - ], + }, + useVisible() { + const collection = useCollection_deprecated(); + return (collection as any).template !== 'view' || collection?.writableView; + }, }, ], +}; + +/** + * @deprecated + * use `kanbanActionInitializers` instead + */ +export const kanbanActionInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'KanbanActionInitializers', + ...commonOptions, }); export const kanbanActionInitializers = new CompatibleSchemaInitializer( { name: 'kanban:configureActions', - title: "{{t('Configure actions')}}", - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'itemGroup', - title: "{{t('Enable actions')}}", - name: 'enableActions', - children: [ - { - name: 'filter', - title: "{{t('Filter')}}", - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'left', - }, - }, - { - name: 'addNew', - title: "{{t('Add new')}}", - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return (collection as any).template !== 'view' || collection?.writableView; - }, - }, - ], - }, - ], + ...commonOptions, }, kanbanActionInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-kanban/src/client/__e2e__/schemaInitailizer.test.ts b/packages/plugins/@nocobase/plugin-kanban/src/client/__e2e__/schemaInitailizer.test.ts index 4b76d07e83..9cdc383e2a 100644 --- a/packages/plugins/@nocobase/plugin-kanban/src/client/__e2e__/schemaInitailizer.test.ts +++ b/packages/plugins/@nocobase/plugin-kanban/src/client/__e2e__/schemaInitailizer.test.ts @@ -89,7 +89,7 @@ test.describe('configure actions', () => { await expect(page.getByLabel('block-item-CardItem-general-kanban')).toBeVisible(); await expect(page.getByLabel('schema-initializer-ActionBar-kanban:configureActions-general')).toBeVisible(); await page.getByLabel('schema-initializer-ActionBar-kanban:configureActions-general').click(); - await page.getByRole('menuitem', { name: 'Filter' }).getByRole('switch').click(); + await page.getByRole('menuitem', { name: 'Filter' }).click(); //按钮正常显示 await expect(page.getByLabel('action-Filter.Action-Filter-filter-general-kanban')).toBeVisible(); }); @@ -97,13 +97,14 @@ test.describe('configure actions', () => { const nocoPage = await mockPage(oneEmptyKanbanBlock).waitForInit(); await nocoPage.goto(); await page.getByLabel('schema-initializer-ActionBar-kanban:configureActions-general').hover(); - await page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch').click(); + await page.getByRole('menuitem', { name: 'Add new' }).click(); //按钮正常显示 await expect(page.getByLabel('action-Action-Add ')).toBeVisible(); //添加数据 await page.getByLabel('action-Action-Add new-create-general-kanban').click(); await page.getByLabel('schema-initializer-Grid-popup:addNew:addBlock-general').hover(); - await page.getByRole('menuitem', { name: 'form Form' }).click(); + await page.getByRole('menuitem', { name: 'form Form' }).hover(); + await page.getByRole('menuitem', { name: 'Current collection' }).click(); await page.mouse.move(300, 0); await page.getByLabel('schema-initializer-Grid-form:configureFields-general').hover(); await page.getByRole('menuitem', { name: 'Single Select' }).click(); diff --git a/packages/plugins/@nocobase/plugin-map/src/client/block/MapActionInitializers.tsx b/packages/plugins/@nocobase/plugin-map/src/client/block/MapActionInitializers.tsx index 4393bd4c36..7c6234e657 100644 --- a/packages/plugins/@nocobase/plugin-map/src/client/block/MapActionInitializers.tsx +++ b/packages/plugins/@nocobase/plugin-map/src/client/block/MapActionInitializers.tsx @@ -9,13 +9,7 @@ import { CompatibleSchemaInitializer, useCollection_deprecated } from '@nocobase/client'; -/** - * @deprecated - * use `mapActionInitializers` instead - * 表格操作配置 - */ -export const mapActionInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'MapActionInitializers', +const commonOptions = { title: "{{t('Configure actions')}}", icon: 'SettingOutlined', style: { @@ -23,132 +17,54 @@ export const mapActionInitializers_deprecated = new CompatibleSchemaInitializer( }, items: [ { - type: 'itemGroup', - title: "{{t('Enable actions')}}", - name: 'enableActions', - children: [ - { - name: 'filter', - title: "{{t('Filter')}}", - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'left', - }, - }, - { - name: 'addNew', - title: "{{t('Add new')}}", - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return collection.template !== 'sql'; - }, - }, - { - name: 'refresh', - title: "{{t('Refresh')}}", - Component: 'RefreshActionInitializer', - schema: { - 'x-align': 'right', - }, - }, - ], + name: 'filter', + title: "{{t('Filter')}}", + Component: 'FilterActionInitializer', + schema: { + 'x-align': 'left', + }, }, { - name: 'divider', - type: 'divider', + name: 'addNew', + title: "{{t('Add new')}}", + Component: 'CreateActionInitializer', + schema: { + 'x-align': 'right', + 'x-decorator': 'ACLActionProvider', + 'x-acl-action-props': { + skipScopeCheck: true, + }, + }, useVisible() { const collection = useCollection_deprecated(); return collection.template !== 'sql'; }, }, { - type: 'subMenu', - title: '{{t("Customize")}}', - name: 'customize', - children: [], - useVisible() { - const collection = useCollection_deprecated(); - return collection.template !== 'sql'; + name: 'refresh', + title: "{{t('Refresh')}}", + Component: 'RefreshActionInitializer', + schema: { + 'x-align': 'right', }, }, ], +}; + +/** + * @deprecated + * use `mapActionInitializers` instead + * 表格操作配置 + */ +export const mapActionInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'MapActionInitializers', + ...commonOptions, }); export const mapActionInitializers = new CompatibleSchemaInitializer( { name: 'map:configureActions', - title: "{{t('Configure actions')}}", - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'itemGroup', - title: "{{t('Enable actions')}}", - name: 'enableActions', - children: [ - { - name: 'filter', - title: "{{t('Filter')}}", - Component: 'FilterActionInitializer', - schema: { - 'x-align': 'left', - }, - }, - { - name: 'addNew', - title: "{{t('Add new')}}", - Component: 'CreateActionInitializer', - schema: { - 'x-align': 'right', - 'x-decorator': 'ACLActionProvider', - 'x-acl-action-props': { - skipScopeCheck: true, - }, - }, - useVisible() { - const collection = useCollection_deprecated(); - return collection.template !== 'sql'; - }, - }, - { - name: 'refresh', - title: "{{t('Refresh')}}", - Component: 'RefreshActionInitializer', - schema: { - 'x-align': 'right', - }, - }, - ], - }, - { - name: 'divider', - type: 'divider', - useVisible() { - const collection = useCollection_deprecated(); - return collection.template !== 'sql'; - }, - }, - { - type: 'subMenu', - title: '{{t("Customize")}}', - name: 'customize', - children: [], - useVisible() { - const collection = useCollection_deprecated(); - return collection.template !== 'sql'; - }, - }, - ], + ...commonOptions, }, mapActionInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-snapshot-field/src/client/SnapshotBlock/SnapshotBlockInitializers/SnapshotBlockInitializers.tsx b/packages/plugins/@nocobase/plugin-snapshot-field/src/client/SnapshotBlock/SnapshotBlockInitializers/SnapshotBlockInitializers.tsx index 2625baf9fd..84b1748fe9 100644 --- a/packages/plugins/@nocobase/plugin-snapshot-field/src/client/SnapshotBlock/SnapshotBlockInitializers/SnapshotBlockInitializers.tsx +++ b/packages/plugins/@nocobase/plugin-snapshot-field/src/client/SnapshotBlock/SnapshotBlockInitializers/SnapshotBlockInitializers.tsx @@ -10,12 +10,7 @@ import { CompatibleSchemaInitializer, gridRowColWrap } from '@nocobase/client'; import { NAMESPACE } from '../../locale'; -/** - * @deprecated - * use `snapshotBlockInitializers` instead - */ -export const snapshotBlockInitializers_deprecated = new CompatibleSchemaInitializer({ - name: 'SnapshotBlockInitializers', +const commonOptions = { wrap: gridRowColWrap, title: `{{t("Add block", { ns: "${NAMESPACE}" })}}`, icon: 'PlusOutlined', @@ -46,41 +41,21 @@ export const snapshotBlockInitializers_deprecated = new CompatibleSchemaInitiali ], }, ], +}; + +/** + * @deprecated + * use `snapshotBlockInitializers` instead + */ +export const snapshotBlockInitializers_deprecated = new CompatibleSchemaInitializer({ + name: 'SnapshotBlockInitializers', + ...commonOptions, }); export const snapshotBlockInitializers = new CompatibleSchemaInitializer( { name: 'popup:snapshot:addBlock', - wrap: gridRowColWrap, - title: `{{t("Add block", { ns: "${NAMESPACE}" })}}`, - icon: 'PlusOutlined', - items: [ - { - type: 'itemGroup', - title: '{{t("Current record blocks")}}', - name: 'currentRecordBlocks', - children: [ - { - name: 'details', - title: '{{t("Details")}}', - Component: 'SnapshotBlockInitializersDetailItem', - actionInitializers: 'details:configureActions', - }, - ], - }, - { - type: 'itemGroup', - title: '{{t("Other blocks")}}', - name: 'otherBlocks', - children: [ - { - name: 'markdown', - title: '{{t("Markdown")}}', - Component: 'MarkdownBlockInitializer', - }, - ], - }, - ], + ...commonOptions, }, snapshotBlockInitializers_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/__e2e__/configuration1.test.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/__e2e__/configuration1.test.ts index ee18fb59c9..72a4c16b23 100644 --- a/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/__e2e__/configuration1.test.ts +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/__e2e__/configuration1.test.ts @@ -80,11 +80,11 @@ test.describe('Configuration page to configure the Trigger node', () => { await page.getByText('Configure columns').hover(); await page.getByText(triggerNodeFieldDisplayName).click(); await page.getByText('Configure actions').hover(); - await page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch').click(); - await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).toBeEnabled(); + await page.getByRole('menuitem', { name: 'Add new' }).click(); await page.getByLabel(`action-Action-Add new-create-${triggerNodeCollectionName}-table`).click(); await page.getByLabel(`schema-initializer-Grid-popup:addNew:addBlock-${triggerNodeCollectionName}`).hover(); - await page.getByRole('menuitem', { name: 'form Form' }).click(); + await page.getByRole('menuitem', { name: 'form Form' }).hover(); + await page.getByRole('menuitem', { name: 'Current collection' }).click(); // 移开鼠标,关闭菜单 await page.mouse.move(300, 0); await page @@ -183,8 +183,7 @@ test.describe('Configuration page to configure the Trigger node', () => { await page.getByText('Configure columns').hover(); await page.getByText(triggerNodeFieldDisplayName).click(); await page.getByText('Configure actions').hover(); - await page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch').click(); - await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).toBeEnabled(); + await page.getByRole('menuitem', { name: 'Add new' }).click(); await page.getByLabel(`action-Action-Add new-create-${triggerNodeCollectionName}-table`).click(); await page.getByLabel(`schema-initializer-Grid-popup:addNew:addBlock-${triggerNodeCollectionName}`).hover(); @@ -197,7 +196,6 @@ test.describe('Configuration page to configure the Trigger node', () => { await page .getByLabel(`schema-initializer-ActionBar-createForm:configureActions-${triggerNodeCollectionName}`) .hover(); - await page.getByRole('menuitem', { name: 'Customize' }).hover(); await page.getByRole('menuitem', { name: 'Submit to workflow' }).click(); await page.getByLabel(`schema-initializer-Grid-form:configureFields-${triggerNodeCollectionName}`).hover(); await page.getByRole('menuitem', { name: `${triggerNodeFieldDisplayName}` }).click(); diff --git a/packages/plugins/@nocobase/plugin-workflow-manual/src/client/instruction/SchemaConfig.tsx b/packages/plugins/@nocobase/plugin-workflow-manual/src/client/instruction/SchemaConfig.tsx index 704891f25a..5f049a3367 100644 --- a/packages/plugins/@nocobase/plugin-workflow-manual/src/client/instruction/SchemaConfig.tsx +++ b/packages/plugins/@nocobase/plugin-workflow-manual/src/client/instruction/SchemaConfig.tsx @@ -108,17 +108,7 @@ function useTriggerInitializers(): SchemaInitializerItemType | null { return trigger.useInitializers ? trigger.useInitializers(workflow.config) : null; } -const blockTypeNames = { - customForm: customRecordForm.title, - record: `{{t("Data record", { ns: "${NAMESPACE}" })}}`, -}; - -/** - * @deprecated - * use `addBlockButton` instead - */ -export const addBlockButton_deprecated = new CompatibleSchemaInitializer({ - name: 'AddBlockButton', +const popupConfigureUserInterfaceOptions = { wrap: gridRowColWrap, title: '{{t("Add block")}}', items: [ @@ -145,7 +135,7 @@ export const addBlockButton_deprecated = new CompatibleSchemaInitializer({ { name: 'nodes', type: 'subMenu', - title: `{{t("Node result", { ns: "workflow" })}}`, + title: `{{t("Node result", { ns: "${NAMESPACE}" })}}`, children: nodeBlockInitializers, }, ] @@ -180,72 +170,21 @@ export const addBlockButton_deprecated = new CompatibleSchemaInitializer({ ], }, ], +}; + +/** + * @deprecated + * use `addBlockButton` instead + */ +export const addBlockButton_deprecated = new CompatibleSchemaInitializer({ + name: 'AddBlockButton', + ...popupConfigureUserInterfaceOptions, }); export const addBlockButton = new CompatibleSchemaInitializer( { name: 'workflowManual:popup:configureUserInterface:addBlock', - wrap: gridRowColWrap, - title: '{{t("Add block")}}', - items: [ - { - type: 'itemGroup', - name: 'dataBlocks', - title: '{{t("Data blocks")}}', - hideIfNoChildren: true, - useChildren() { - const workflowPlugin = usePlugin(WorkflowPlugin); - const current = useNodeContext(); - const nodes = useAvailableUpstreams(current); - const triggerInitializers = [useTriggerInitializers()].filter(Boolean); - const nodeBlockInitializers = nodes - .map((node) => { - const instruction = workflowPlugin.instructions.get(node.type); - return instruction?.useInitializers?.(node); - }) - .filter(Boolean); - const dataBlockInitializers: any = [ - ...triggerInitializers, - ...(nodeBlockInitializers.length - ? [ - { - name: 'nodes', - type: 'subMenu', - title: `{{t("Node result", { ns: "${NAMESPACE}" })}}`, - children: nodeBlockInitializers, - }, - ] - : []), - ].filter(Boolean); - return dataBlockInitializers; - }, - }, - { - type: 'itemGroup', - name: 'form', - title: '{{t("Form")}}', - useChildren() { - const dm = useDataSourceManager(); - const allCollections = dm.getAllCollections(); - return Array.from(manualFormTypes.getValues()).map((item: ManualFormType) => { - const { useInitializer: getInitializer } = item.config; - return getInitializer({ allCollections }); - }); - }, - }, - { - type: 'itemGroup', - name: 'otherBlocks', - title: '{{t("Other blocks")}}', - children: [ - { - name: 'markdown', - title: '{{t("Markdown")}}', - Component: 'MarkdownBlockInitializer', - }, - ], - }, - ], + ...popupConfigureUserInterfaceOptions, }, addBlockButton_deprecated, ); @@ -427,12 +366,7 @@ function ActionInitializer() { ); } -/** - * @deprecated - * use `addActionButton` instead - */ -export const addActionButton_deprecated = new CompatibleSchemaInitializer({ - name: 'AddActionButton', +const formConfigureActionsOptions = { title: '{{t("Configure actions")}}', items: [ { @@ -460,38 +394,21 @@ export const addActionButton_deprecated = new CompatibleSchemaInitializer({ action: JOB_STATUS.PENDING, }, ], +}; + +/** + * @deprecated + * use `addActionButton` instead + */ +export const addActionButton_deprecated = new CompatibleSchemaInitializer({ + name: 'AddActionButton', + ...formConfigureActionsOptions, }); export const addActionButton = new CompatibleSchemaInitializer( { name: 'workflowManual:form:configureActions', - title: '{{t("Configure actions")}}', - items: [ - { - name: 'jobStatusResolved', - title: `{{t("Continue the process", { ns: "${NAMESPACE}" })}}`, - Component: ContinueInitializer, - action: JOB_STATUS.RESOLVED, - actionProps: { - type: 'primary', - }, - }, - { - name: 'jobStatusRejected', - title: `{{t("Terminate the process", { ns: "${NAMESPACE}" })}}`, - Component: ActionInitializer, - action: JOB_STATUS.REJECTED, - actionProps: { - danger: true, - }, - }, - { - name: 'jobStatusPending', - title: `{{t("Save temporarily", { ns: "${NAMESPACE}" })}}`, - Component: ActionInitializer, - action: JOB_STATUS.PENDING, - }, - ], + ...formConfigureActionsOptions, }, addActionButton_deprecated, ); diff --git a/packages/plugins/@nocobase/plugin-workflow-manual/src/client/instruction/forms/custom.tsx b/packages/plugins/@nocobase/plugin-workflow-manual/src/client/instruction/forms/custom.tsx index 0f28d15546..b2b20576e6 100644 --- a/packages/plugins/@nocobase/plugin-workflow-manual/src/client/instruction/forms/custom.tsx +++ b/packages/plugins/@nocobase/plugin-workflow-manual/src/client/instruction/forms/custom.tsx @@ -347,25 +347,26 @@ const CustomItemsComponent = (props) => { ); }; +const commonOptions = { + wrap: gridRowColWrap, + insertPosition: 'beforeEnd', + title: "{{t('Configure fields')}}", + ItemsComponent: CustomItemsComponent, +}; + /** * @deprecated * use `addCustomFormField` instead */ export const addCustomFormField_deprecated = new CompatibleSchemaInitializer({ name: 'AddCustomFormField', - wrap: gridRowColWrap, - insertPosition: 'beforeEnd', - title: "{{t('Configure fields')}}", - ItemsComponent: CustomItemsComponent, + ...commonOptions, }); export const addCustomFormField = new CompatibleSchemaInitializer( { name: 'workflowManual:customForm:configureFields', - wrap: gridRowColWrap, - insertPosition: 'beforeEnd', - title: "{{t('Configure fields')}}", - ItemsComponent: CustomItemsComponent, + ...commonOptions, }, addCustomFormField_deprecated, );