From d75db227770079bab907b5b5880e473cbb26245a Mon Sep 17 00:00:00 2001
From: Zeke Zhang <958414905@qq.com>
Date: Sun, 7 Apr 2024 17:21:26 +0800
Subject: [PATCH] fix(connect-data-blocks): should immediately show in the
drop-down menu (#3953)
* test: add e2e tests
* fix: should immediately show in the drop-down menu
* fix: should not lose the filtering function when dragging and connecting
---
.../src/filter-provider/FilterProvider.tsx | 16 +-
.../table/__e2e__/schemaSettings.test.ts | 87 +++++++-
.../table/__e2e__/templatesOfBug.ts | 190 ++++++++++++++++++
.../src/schema-settings/SchemaSettings.tsx | 2 +
4 files changed, 281 insertions(+), 14 deletions(-)
diff --git a/packages/core/client/src/filter-provider/FilterProvider.tsx b/packages/core/client/src/filter-provider/FilterProvider.tsx
index 730a30efb1..05c0d1904a 100644
--- a/packages/core/client/src/filter-provider/FilterProvider.tsx
+++ b/packages/core/client/src/filter-provider/FilterProvider.tsx
@@ -91,7 +91,7 @@ export const DataBlockCollector = ({
params?: { filter: FilterParam };
}) => {
const collection = useCollection_deprecated();
- const { recordDataBlocks, removeDataBlock } = useFilterBlock();
+ const { recordDataBlocks } = useFilterBlock();
const { service } = useBlockRequestContext();
const field = useField();
const fieldSchema = useFieldSchema();
@@ -153,12 +153,6 @@ export const DataBlockCollector = ({
if (shouldApplyFilter) addBlockToDataBlocks();
}, [addBlockToDataBlocks, shouldApplyFilter]);
- useEffect(() => {
- return () => {
- removeDataBlock(fieldSchema['x-uid']);
- };
- }, []);
-
return
{children}
;
};
@@ -185,18 +179,14 @@ export const useFilterBlock = () => {
if (existingBlock) {
// 这里的值有可能会变化,所以需要更新
- existingBlock.service = block.service;
- existingBlock.defaultFilter = block.defaultFilter;
- existingBlock.dataLoadingMode = block.dataLoadingMode;
+ Object.assign(existingBlock, block);
return;
}
// 由于 setDataBlocks 是异步操作,所以上面的 existingBlock 在判断时有可能用的是旧的 dataBlocks,所以下面还需要根据 uid 进行去重操作
setDataBlocks((prev) => uniqBy([...prev, block], 'uid'));
};
const removeDataBlock = (uid: string) => {
- const blocks = dataBlocks.filter((item) => item.uid !== uid);
- if (blocks.length === dataBlocks.length) return;
-
+ if (dataBlocks.every((item) => item.uid !== uid)) return;
setDataBlocks((prev) => prev.filter((item) => item.uid !== uid));
};
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 9780a378b3..1afffa2291 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
@@ -10,7 +10,7 @@ import {
twoTableWithAssociationFields,
twoTableWithSameCollection,
} from '@nocobase/test/e2e';
-import { T3843 } from './templatesOfBug';
+import { T3843, oneTableWithRoles } from './templatesOfBug';
test.describe('table block schema settings', () => {
test('supported options', async ({ page, mockPage }) => {
@@ -287,6 +287,91 @@ test.describe('table block schema settings', () => {
});
test('connecting two blocks connected by a foreign key', async ({ page, mockPage, mockRecords }) => {});
+
+ test('should immediately show in the drop-down menu of Connect data blocks when adding a block for the first time', async ({
+ page,
+ mockPage,
+ }) => {
+ await mockPage(oneTableWithRoles).goto();
+
+ // 1. 创建一个详情区块
+ await page.getByLabel('schema-initializer-Grid-page:').hover();
+ await page.getByRole('menuitem', { name: 'table Details right' }).hover();
+ await page.getByRole('menuitem', { name: 'Roles' }).click();
+ await page.mouse.move(300, 0);
+ await page.getByLabel('schema-initializer-Grid-details:configureFields-roles').hover();
+ await page.getByRole('menuitem', { name: 'Role name' }).click();
+ await page.mouse.move(300, 0);
+
+ // 2. 创建的详情区块应该立即出现在 Connect data blocks 的下拉菜单中
+ await page.getByLabel('block-item-CardItem-roles-table').hover();
+ await page.getByLabel('designer-schema-settings-CardItem-blockSettings:table-roles').hover();
+ await page.getByRole('menuitem', { name: 'Connect data blocks right' }).hover();
+ await page.getByRole('menuitem', { name: 'Roles #' }).click();
+
+ // 3. 点击 Table 行,筛选功能应该正常
+ // 初次点击,变为选中状态
+ await page.getByRole('button', { name: 'Admin' }).click();
+ await expect(page.getByLabel('block-item-CollectionField-').getByText('Admin')).toBeVisible();
+ // 再次点击,取消选中状态
+ await page.getByRole('button', { name: 'Admin' }).click();
+ await expect(page.getByLabel('block-item-CollectionField-').getByText('Admin')).toBeHidden();
+
+ // 4. 删除详情区块,Connect data blocks 的下拉菜单应该立即消失
+ await page.getByLabel('block-item-CardItem-roles-details').hover();
+ await page.getByLabel('designer-schema-settings-CardItem-blockSettings:detailsWithPagination-roles').hover();
+ await page.getByRole('menuitem', { name: 'Delete' }).click();
+ await page.getByRole('button', { name: 'OK', exact: true }).click();
+
+ await page.getByLabel('block-item-CardItem-roles-').hover();
+ await page.getByLabel('designer-schema-settings-CardItem-blockSettings:table-roles').hover();
+ await page.getByRole('menuitem', { name: 'Connect data blocks right' }).hover();
+ await expect(page.getByRole('menuitem', { name: 'No blocks to connect' })).toBeVisible();
+ });
+
+ test('should not lose the filtering function when dragging and connecting', async ({ page, mockPage }) => {
+ await mockPage(oneTableWithRoles).goto();
+
+ // 1. 创建一个详情区块
+ await page.getByLabel('schema-initializer-Grid-page:').hover();
+ await page.getByRole('menuitem', { name: 'table Details right' }).hover();
+ await page.getByRole('menuitem', { name: 'Roles' }).click();
+ await page.mouse.move(300, 0);
+ await page.getByLabel('schema-initializer-Grid-details:configureFields-roles').hover();
+ await page.getByRole('menuitem', { name: 'Role name' }).click();
+ await page.mouse.move(300, 0);
+
+ // 2. 拖动详情区块
+ await page.getByLabel('block-item-CardItem-roles-details').hover();
+ await page
+ .getByLabel('designer-drag-handler-CardItem-blockSettings:detailsWithPagination-roles')
+ .dragTo(page.getByLabel('block-item-CardItem-roles-table'));
+
+ // 3. 创建的详情区块应该立即出现在 Connect data blocks 的下拉菜单中
+ await page.getByLabel('block-item-CardItem-roles-table').hover();
+ await page.getByLabel('designer-schema-settings-CardItem-blockSettings:table-roles').hover();
+ await page.getByRole('menuitem', { name: 'Connect data blocks right' }).hover();
+ await page.getByRole('menuitem', { name: 'Roles #' }).click();
+
+ // 4. 点击 Table 行,筛选功能应该正常
+ // 初次点击,变为选中状态
+ await page.getByRole('button', { name: 'Admin' }).click();
+ await expect(page.getByLabel('block-item-CollectionField-').getByText('Admin')).toBeVisible();
+ // 再次点击,取消选中状态
+ await page.getByRole('button', { name: 'Admin' }).click();
+ await expect(page.getByLabel('block-item-CollectionField-').getByText('Admin')).toBeHidden();
+
+ // 5. 删除详情区块,Connect data blocks 的下拉菜单应该立即消失
+ await page.getByLabel('block-item-CardItem-roles-details').hover();
+ await page.getByLabel('designer-schema-settings-CardItem-blockSettings:detailsWithPagination-roles').hover();
+ await page.getByRole('menuitem', { name: 'Delete' }).click();
+ await page.getByRole('button', { name: 'OK', exact: true }).click();
+
+ await page.getByLabel('block-item-CardItem-roles-').hover();
+ await page.getByLabel('designer-schema-settings-CardItem-blockSettings:table-roles').hover();
+ await page.getByRole('menuitem', { name: 'Connect data blocks right' }).hover();
+ await expect(page.getByRole('menuitem', { name: 'No blocks to connect' })).toBeVisible();
+ });
});
});
diff --git a/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/templatesOfBug.ts b/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/templatesOfBug.ts
index eaf53302ab..b72b822c61 100644
--- a/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/templatesOfBug.ts
+++ b/packages/core/client/src/modules/blocks/data-blocks/table/__e2e__/templatesOfBug.ts
@@ -1169,3 +1169,193 @@ export const T3843 = {
'x-async': true,
},
};
+export const oneTableWithRoles: PageConfig = {
+ pageSchema: {
+ _isJSONSchemaObject: true,
+ version: '2.0',
+ type: 'void',
+ 'x-component': 'Page',
+ 'x-app-version': '0.21.0-alpha.5',
+ properties: {
+ g31hdrdqs8h: {
+ _isJSONSchemaObject: true,
+ version: '2.0',
+ type: 'void',
+ 'x-component': 'Grid',
+ 'x-initializer': 'page:addBlock',
+ 'x-app-version': '0.21.0-alpha.5',
+ properties: {
+ w3qd8et7ny1: {
+ _isJSONSchemaObject: true,
+ version: '2.0',
+ type: 'void',
+ 'x-component': 'Grid.Row',
+ 'x-app-version': '0.21.0-alpha.5',
+ properties: {
+ jy1b9o63ko7: {
+ _isJSONSchemaObject: true,
+ version: '2.0',
+ type: 'void',
+ 'x-component': 'Grid.Col',
+ 'x-app-version': '0.21.0-alpha.5',
+ properties: {
+ iwtxze1jmpm: {
+ 'x-uid': 'exvpbgr35zn',
+ _isJSONSchemaObject: true,
+ version: '2.0',
+ type: 'void',
+ 'x-decorator': 'TableBlockProvider',
+ 'x-acl-action': 'roles:list',
+ 'x-use-decorator-props': 'useTableBlockDecoratorProps',
+ 'x-decorator-props': {
+ collection: 'roles',
+ dataSource: 'main',
+ action: 'list',
+ params: {
+ pageSize: 20,
+ },
+ rowKey: 'name',
+ showIndex: true,
+ dragSort: false,
+ },
+ 'x-toolbar': 'BlockSchemaToolbar',
+ 'x-settings': 'blockSettings:table',
+ 'x-component': 'CardItem',
+ 'x-filter-targets': [
+ {
+ uid: 'a7n5crnwx91',
+ },
+ {
+ uid: 'z10rv1j5j7x',
+ field: 'roles.name',
+ },
+ ],
+ 'x-app-version': '0.21.0-alpha.5',
+ properties: {
+ actions: {
+ _isJSONSchemaObject: true,
+ version: '2.0',
+ type: 'void',
+ 'x-initializer': 'table:configureActions',
+ 'x-component': 'ActionBar',
+ 'x-component-props': {
+ style: {
+ marginBottom: 'var(--nb-spacing)',
+ },
+ },
+ 'x-app-version': '0.21.0-alpha.5',
+ 'x-uid': 'bz6xai67sd4',
+ 'x-async': false,
+ 'x-index': 1,
+ },
+ '3r100r39y9k': {
+ _isJSONSchemaObject: true,
+ version: '2.0',
+ type: 'array',
+ 'x-initializer': 'table:configureColumns',
+ 'x-component': 'TableV2',
+ 'x-use-component-props': 'useTableBlockProps',
+ 'x-component-props': {
+ rowKey: 'id',
+ rowSelection: {
+ type: 'checkbox',
+ },
+ },
+ 'x-app-version': '0.21.0-alpha.5',
+ properties: {
+ actions: {
+ _isJSONSchemaObject: true,
+ version: '2.0',
+ type: 'void',
+ title: '{{ t("Actions") }}',
+ 'x-action-column': 'actions',
+ 'x-decorator': 'TableV2.Column.ActionBar',
+ 'x-component': 'TableV2.Column',
+ 'x-designer': 'TableV2.ActionColumnDesigner',
+ 'x-initializer': 'table:configureItemActions',
+ 'x-app-version': '0.21.0-alpha.5',
+ properties: {
+ huffguvj9ju: {
+ _isJSONSchemaObject: true,
+ version: '2.0',
+ type: 'void',
+ 'x-decorator': 'DndContext',
+ 'x-component': 'Space',
+ 'x-component-props': {
+ split: '|',
+ },
+ 'x-app-version': '0.21.0-alpha.5',
+ 'x-uid': 'kumec65v6eo',
+ 'x-async': false,
+ 'x-index': 1,
+ },
+ },
+ 'x-uid': '0behu2op8h2',
+ 'x-async': false,
+ 'x-index': 1,
+ },
+ o3kdcl5v6ex: {
+ _isJSONSchemaObject: true,
+ version: '2.0',
+ type: 'void',
+ 'x-decorator': 'TableV2.Column.Decorator',
+ 'x-toolbar': 'TableColumnSchemaToolbar',
+ 'x-settings': 'fieldSettings:TableColumn',
+ 'x-component': 'TableV2.Column',
+ 'x-app-version': '0.21.0-alpha.5',
+ properties: {
+ title: {
+ _isJSONSchemaObject: true,
+ version: '2.0',
+ 'x-collection-field': 'roles.title',
+ 'x-component': 'CollectionField',
+ 'x-component-props': {
+ ellipsis: true,
+ },
+ 'x-read-pretty': true,
+ 'x-decorator': null,
+ 'x-decorator-props': {
+ labelStyle: {
+ display: 'none',
+ },
+ },
+ 'x-app-version': '0.21.0-alpha.5',
+ 'x-uid': 'yga0n3a2puj',
+ 'x-async': false,
+ 'x-index': 1,
+ },
+ },
+ 'x-uid': 'd452dent98m',
+ 'x-async': false,
+ 'x-index': 2,
+ },
+ },
+ 'x-uid': 'byorarf2lw2',
+ 'x-async': false,
+ 'x-index': 2,
+ },
+ },
+ 'x-async': false,
+ 'x-index': 1,
+ },
+ },
+ 'x-uid': 'ousy05pzp3u',
+ 'x-async': false,
+ 'x-index': 1,
+ },
+ },
+ 'x-uid': 'znu51ytf7f5',
+ 'x-async': false,
+ 'x-index': 1,
+ },
+ },
+ 'x-uid': 'gvzvz05oi9h',
+ 'x-async': false,
+ 'x-index': 1,
+ },
+ },
+ 'x-uid': 'mk589w74bvs',
+ 'x-async': true,
+ 'x-index': 1,
+ },
+};
diff --git a/packages/core/client/src/schema-settings/SchemaSettings.tsx b/packages/core/client/src/schema-settings/SchemaSettings.tsx
index 7f347d5519..54081cfe0c 100644
--- a/packages/core/client/src/schema-settings/SchemaSettings.tsx
+++ b/packages/core/client/src/schema-settings/SchemaSettings.tsx
@@ -553,6 +553,7 @@ export const SchemaSettingsRemove: FC = (props) => {
const form = useForm();
const { modal } = App.useApp();
const { removeActiveFieldName } = useFormActiveFields() || {};
+ const { removeDataBlock } = useFilterBlock();
return (
= (props) => {
field.setInitialValue(null);
field.reset();
}
+ removeDataBlock(fieldSchema['x-uid']);
},
});
}}