fix(associationBlock): fix association blocks for parent collection f… (#3813)

* fix(associationBlock): fix association blocks for parent collection fields

* test: add e2e
This commit is contained in:
Zeke Zhang 2024-03-26 11:42:46 +08:00 committed by GitHub
parent b690a3afd1
commit e3d8a95809
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 317 additions and 5 deletions

View File

@ -1,4 +1,10 @@
import { useCollection, useCollectionManager, useCollectionParentRecordData, useCollectionRecordData } from '../..'; import {
InheritanceCollectionMixin,
useCollection,
useCollectionManager,
useCollectionParentRecordData,
useCollectionRecordData,
} from '../..';
/** /**
* schema sourceId * schema sourceId
@ -11,14 +17,17 @@ export const useDataBlockSourceId = ({ association }: { association: string }) =
const recordData = useCollectionRecordData(); const recordData = useCollectionRecordData();
const parentRecordData = useCollectionParentRecordData(); const parentRecordData = useCollectionParentRecordData();
const cm = useCollectionManager(); const cm = useCollectionManager();
const collectionOutsideBlock = useCollection(); const collectionOutsideBlock = useCollection<InheritanceCollectionMixin>();
if (!association) return; if (!association) return;
const associationField = cm.getCollectionField(association); const associationField = cm.getCollectionField(association);
const associationCollection = cm.getCollection(associationField.collectionName); const associationCollection = cm.getCollection<InheritanceCollectionMixin>(associationField.collectionName);
if (collectionOutsideBlock.name === associationCollection.name) { if (
collectionOutsideBlock.name === associationCollection.name ||
collectionOutsideBlock.getParentCollectionsName?.().includes(associationCollection.name)
) {
return recordData?.[ return recordData?.[
associationField.sourceKey || associationField.sourceKey ||
associationCollection.filterTargetKey || associationCollection.filterTargetKey ||

View File

@ -1,4 +1,5 @@
import { createBlockInPage, expect, oneEmptyTable, test } from '@nocobase/test/e2e'; import { createBlockInPage, expect, oneEmptyTable, test } from '@nocobase/test/e2e';
import { T3686 } from './templatesOfBug';
test.describe('where table block can be added', () => { test.describe('where table block can be added', () => {
test('page', async ({ page, mockPage }) => { test('page', async ({ page, mockPage }) => {
@ -9,7 +10,45 @@ test.describe('where table block can be added', () => {
await expect(page.getByLabel('block-item-CardItem-users-table')).toBeVisible(); await expect(page.getByLabel('block-item-CardItem-users-table')).toBeVisible();
}); });
test('popup', async () => {}); test('popup', async ({ page, mockPage, mockRecord }) => {
await mockPage(T3686).goto();
await mockRecord('parentCollection');
const childRecord = await mockRecord('childCollection');
// 打开弹窗
await page.getByLabel('action-Action.Link-View').click();
// 添加当前表关系区块
await page.getByLabel('schema-initializer-Grid-popup').hover();
await page.getByRole('menuitem', { name: 'table Table right' }).hover();
await page.getByRole('menuitem', { name: 'childAssociationField ->' }).click();
await page
.getByTestId('drawer-Action.Container-childCollection-View record')
.getByLabel('schema-initializer-TableV2-')
.hover();
await page.getByRole('menuitem', { name: 'childTargetText' }).click();
// 添加父表关系区块
await page.getByLabel('schema-initializer-Grid-popup').hover();
await page.getByRole('menuitem', { name: 'table Table right' }).hover();
await page.getByRole('menuitem', { name: 'parentAssociationField ->' }).click();
await page.getByLabel('schema-initializer-TableV2-table:configureColumns-parentTargetCollection').hover();
await page.getByRole('menuitem', { name: 'parentTargetText' }).click();
// 普通关系区块应该显示正常
await expect(
page
.getByLabel('block-item-CardItem-childTargetCollection-table')
.getByText(childRecord.childAssociationField[0].childTargetText),
).toBeVisible();
// 父表关系区块应该显示正常
await expect(
page
.getByLabel('block-item-CardItem-parentTargetCollection-table')
.getByText(childRecord.parentAssociationField[0].parentTargetText),
).toBeVisible();
});
}); });
test.describe('configure actions', () => { test.describe('configure actions', () => {

View File

@ -1,3 +1,5 @@
import { PageConfig } from '@nocobase/test/e2e';
export const T2183 = { export const T2183 = {
pageSchema: { pageSchema: {
_isJSONSchemaObject: true, _isJSONSchemaObject: true,
@ -670,3 +672,260 @@ export const T2187 = {
'x-index': 1, 'x-index': 1,
}, },
}; };
export const T3686: PageConfig = {
collections: [
{
name: 'parentTargetCollection',
fields: [
{
name: 'parentTargetText',
interface: 'input',
},
],
},
{
name: 'childTargetCollection',
fields: [
{
name: 'childTargetText',
interface: 'input',
},
],
},
{
name: 'childCollection',
inherits: ['parentCollection'],
fields: [
{
name: 'childAssociationField',
interface: 'm2m',
target: 'childTargetCollection',
},
],
},
{
name: 'parentCollection',
fields: [
{
name: 'parentAssociationField',
interface: 'm2m',
target: 'parentTargetCollection',
},
],
},
],
pageSchema: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Page',
properties: {
fa2wzem9pud: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'page:addBlock',
properties: {
'14kr5bu1min': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Row',
properties: {
uc0jyubx2p3: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Col',
properties: {
k22vt5rvlf8: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-decorator': 'TableBlockProvider',
'x-acl-action': 'childCollection:list',
'x-use-decorator-props': 'useTableBlockDecoratorProps',
'x-decorator-props': {
collection: 'childCollection',
dataSource: 'main',
action: 'list',
params: {
pageSize: 20,
},
rowKey: 'id',
showIndex: true,
dragSort: false,
},
'x-toolbar': 'BlockSchemaToolbar',
'x-settings': 'blockSettings:table',
'x-component': 'CardItem',
'x-filter-targets': [],
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-uid': '42xfns3215b',
'x-async': false,
'x-index': 1,
},
mv0fpgnz9x4: {
_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',
},
},
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',
properties: {
'4pr5w722wko': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-decorator': 'DndContext',
'x-component': 'Space',
'x-component-props': {
split: '|',
},
properties: {
'0z54f36l29g': {
'x-uid': '6ga7ofdmqac',
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
title: 'View record',
'x-action': 'view',
'x-toolbar': 'ActionSchemaToolbar',
'x-settings': 'actionSettings:view',
'x-component': 'Action.Link',
'x-component-props': {
openMode: 'drawer',
danger: false,
},
'x-decorator': 'ACLActionProvider',
'x-designer-props': {
linkageAction: true,
},
properties: {
drawer: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
title: '{{ t("View record") }}',
'x-component': 'Action.Container',
'x-component-props': {
className: 'nb-action-popup',
},
properties: {
tabs: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Tabs',
'x-component-props': {},
'x-initializer': 'TabPaneInitializers',
properties: {
tab1: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
title: '{{t("Details")}}',
'x-component': 'Tabs.TabPane',
'x-designer': 'Tabs.Designer',
'x-component-props': {},
properties: {
grid: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'popup:common:addBlock',
'x-uid': '8isg655oydv',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'avctzq7wpne',
'x-async': false,
'x-index': 1,
},
},
'x-uid': '8mimixsn47i',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'l491lw6ud7u',
'x-async': false,
'x-index': 1,
},
},
'x-async': false,
'x-index': 1,
},
},
'x-uid': '0y6h0doaa8s',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'cusyvu100n5',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'kp6yhoecxt4',
'x-async': false,
'x-index': 2,
},
},
'x-uid': '6fsjzz00845',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'gbcojp8p120',
'x-async': false,
'x-index': 1,
},
},
'x-uid': '18neqdk2pbg',
'x-async': false,
'x-index': 1,
},
},
'x-uid': '7przcz662jy',
'x-async': false,
'x-index': 1,
},
},
'x-uid': 'teroosp0elp',
'x-async': true,
'x-index': 1,
},
};

View File

@ -53,6 +53,7 @@ export interface CollectionSetting {
* @default false * @default false
*/ */
inherit?: boolean; inherit?: boolean;
inherits?: string[];
category?: any[]; category?: any[];
hidden?: boolean; hidden?: boolean;
description?: string; description?: string;
@ -580,6 +581,10 @@ const deleteCollections = async (collectionNames: string[]) => {
const result = await api.post(`/api/collections:destroy?${params}`, { const result = await api.post(`/api/collections:destroy?${params}`, {
headers, headers,
params: {
// 自动删除依赖于集合的对象(如视图),进而删除依赖于这些对象的所有对象
cascade: true,
},
}); });
if (!result.ok()) { if (!result.ok()) {