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 306db3f149..5eb031039b 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 @@ -11,7 +11,7 @@ import { twoTableWithAssociationFields, twoTableWithSameCollection, } from '@nocobase/test/e2e'; -import { T3843, oneTableWithRoles } from './templatesOfBug'; +import { T3843, T4032, oneTableWithRoles } from './templatesOfBug'; test.describe('table block schema settings', () => { test('supported options', async ({ page, mockPage }) => { @@ -192,6 +192,24 @@ test.describe('table block schema settings', () => { await expect(page.getByRole('row')).toHaveCount(2); await expect(page.getByRole('cell', { name: 'Super Admin', exact: true })).toBeVisible(); }); + + // https://nocobase.height.app/T-4032 + test('parent record variable', async ({ page, mockPage }) => { + await mockPage(T4032).goto(); + + // 1. 打开弹窗,弹窗中的表格设置了数据范围:roles.name 包含当前用户的 roles.name + await page.getByLabel('action-Action.Link-View').click(); + await page.waitForTimeout(1000); + + // 2. 断言 + // 不应该弹出错误提示 + await expect(page.locator('.ant-notification-notice')).not.toBeVisible(); + + // 应该显示出三条数据:root,admin,member + await expect(page.getByLabel('block-item-CardItem-roles-').getByText('root')).toBeVisible(); + await expect(page.getByLabel('block-item-CardItem-roles-').getByText('admin')).toBeVisible(); + await expect(page.getByLabel('block-item-CardItem-roles-').getByText('member')).toBeVisible(); + }); }); test.describe('set default sorting rules', () => { 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 b72b822c61..9be98a73a4 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 @@ -1359,3 +1359,393 @@ export const oneTableWithRoles: PageConfig = { 'x-index': 1, }, }; +export const T4032 = { + pageSchema: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Page', + 'x-app-version': '0.21.0-alpha.7', + properties: { + ia9qjfjq6ut: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': 'page:addBlock', + 'x-app-version': '0.21.0-alpha.7', + properties: { + vram4b0bqi3: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + 'x-app-version': '0.21.0-alpha.7', + properties: { + r7uz3lgyh2c: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + 'x-app-version': '0.21.0-alpha.7', + properties: { + y2df95i695g: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'TableBlockProvider', + 'x-acl-action': 'users:list', + 'x-use-decorator-props': 'useTableBlockDecoratorProps', + 'x-decorator-props': { + collection: 'users', + 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': [], + 'x-app-version': '0.21.0-alpha.7', + 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.7', + 'x-uid': '7neytjs0okh', + 'x-async': false, + 'x-index': 1, + }, + yqrkzme65ck: { + _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.7', + 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.7', + properties: { + ma3v2fqbahw: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'DndContext', + 'x-component': 'Space', + 'x-component-props': { + split: '|', + }, + 'x-app-version': '0.21.0-alpha.7', + properties: { + nj1t0730zg4: { + 'x-uid': '89yj46b175h', + _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': 'popup:addTab', + 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', + properties: { + '0tzpts0nsqz': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + 'x-app-version': '0.21.0-alpha.7', + properties: { + picgjevt3op: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + 'x-app-version': '0.21.0-alpha.7', + properties: { + tgwndkbv0ec: { + 'x-uid': 'k0s4o4lb2mm', + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'TableBlockProvider', + 'x-acl-action': 'undefined:list', + 'x-use-decorator-props': 'useTableBlockDecoratorProps', + 'x-decorator-props': { + association: 'users.roles', + dataSource: 'main', + action: 'list', + params: { + pageSize: 20, + filter: { + $and: [ + { + name: { + $includes: '{{$nParentRecord.roles.name}}', + }, + }, + ], + }, + }, + rowKey: 'name', + showIndex: true, + dragSort: false, + }, + 'x-toolbar': 'BlockSchemaToolbar', + 'x-settings': 'blockSettings:table', + 'x-component': 'CardItem', + 'x-filter-targets': [], + 'x-app-version': '0.21.0-alpha.7', + 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.7', + 'x-uid': 'srqykzq3gvg', + 'x-async': false, + 'x-index': 1, + }, + '2yiprrlp7xi': { + _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.7', + 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.7', + properties: { + hz9blh44g22: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'DndContext', + 'x-component': 'Space', + 'x-component-props': { + split: '|', + }, + 'x-app-version': '0.21.0-alpha.7', + 'x-uid': '2br0vnxmz9n', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '7wsmeh6k32c', + 'x-async': false, + 'x-index': 1, + }, + cym3lb5sm0b: { + _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.7', + properties: { + name: { + _isJSONSchemaObject: true, + version: '2.0', + 'x-collection-field': 'roles.name', + '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.7', + 'x-uid': 'lzsfqsbmrlw', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'lrkwqiscrd5', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': '0vmljpu5po8', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'om40j9skoi3', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '9tx487d7jnx', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'uf5mhszv8e4', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'upske4n9wvz', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'g45op4hkqfd', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '8ipxtvpkgz7', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'dkq7q7uiaoe', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '92gsuwjwj4m', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'puh6b9wk3pc', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': '7zch9vwg8vf', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '8fxz2u9zf1c', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'z7raph3uxea', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'kplbtsys5d8', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'vfmzhh0sq2a', + 'x-async': true, + 'x-index': 1, + }, +}; diff --git a/packages/core/client/src/schema-settings/VariableInput/hooks/useParentRecordVariable.ts b/packages/core/client/src/schema-settings/VariableInput/hooks/useParentRecordVariable.ts index c7c0255047..2067a13e45 100644 --- a/packages/core/client/src/schema-settings/VariableInput/hooks/useParentRecordVariable.ts +++ b/packages/core/client/src/schema-settings/VariableInput/hooks/useParentRecordVariable.ts @@ -1,6 +1,7 @@ import { Schema } from '@formily/json-schema'; import { useTranslation } from 'react-i18next'; import { CollectionFieldOptions_deprecated } from '../../../collection-manager'; +import { useCollection } from '../../../data-source'; import { useCollectionRecord } from '../../../data-source/collection-record/CollectionRecordProvider'; import { useParentCollection } from '../../../data-source/collection/AssociationProvider'; import { useFlag } from '../../../flag-provider/hooks/useFlag'; @@ -47,15 +48,17 @@ export const useParentRecordVariable = (props: Props) => { export const useCurrentParentRecordVariable = (props: Props = {}) => { const { t } = useTranslation(); const record = useCollectionRecord(); - const { name: parentCollectionName, dataSource } = useParentCollection() || {}; + const { name: parentCollectionName, dataSource: parentDataSource } = useParentCollection() || {}; + const collection = useCollection(); const { isInSubForm, isInSubTable } = useFlag() || {}; + const dataSource = parentCollectionName ? parentDataSource : collection?.dataSource; const currentParentRecordSettings = useBaseVariable({ collectionField: props.collectionField, uiSchema: props.schema, name: '$nParentRecord', title: t('Parent record'), - collectionName: parentCollectionName, + collectionName: parentCollectionName || collection?.name, noDisabled: props.noDisabled, targetFieldSchema: props.targetFieldSchema, dataSource, @@ -63,9 +66,12 @@ export const useCurrentParentRecordVariable = (props: Props = {}) => { return { currentParentRecordSettings, - currentParentRecordCtx: record?.parentRecord?.data, + // 当该变量使用在区块数据范围的时候,由于某些区块(如 Table)是在 DataBlockProvider 之前解析 filter 的, + // 导致此时 record.parentRecord 的值还是空的,此时正确的值应该是 record,所以在后面加了 record?.data 来防止这种情况 + currentParentRecordCtx: record?.parentRecord?.data || record?.data, shouldDisplayCurrentParentRecord: !!record?.parentRecord?.data && !isInSubForm && !isInSubTable, - collectionName: parentCollectionName, + // 在后面加上 collection?.name 的原因如上面的变量一样 + collectionName: parentCollectionName || collection?.name, dataSource, }; };