fix(variable): resolve the issue of incorrect sourceKey in variable lazy loading (#4691)

* test: add e2e test

* fix(variable): resolve the issue of incorrect sourceKey in variable lazy loading

* chore: optimize e2e test

* chore: fix unit tests

* chore: make e2e more stable
This commit is contained in:
Zeke Zhang 2024-06-18 19:28:22 +08:00 committed by GitHub
parent ac472efd23
commit 6e0074fb66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 276 additions and 6 deletions

View File

@ -13,7 +13,7 @@ import {
oneSubformWithMultiLevelAssociationFields,
test,
} from '@nocobase/test/e2e';
import { T2614, T2615, T2845, T2993 } from './templatesOfBug';
import { T2614, T2615, T2845, T2993, T4596 } from './templatesOfBug';
test.describe('display association fields', () => {
test('form: should display correctly', async ({ page, mockPage, mockRecord }) => {
@ -188,4 +188,22 @@ test.describe('display association fields', () => {
new RegExp(record.m2o.m2oOfTarget1.m2oOfTarget2.nickname),
);
});
// https://nocobase.height.app/T-4596
test('Non-ID source key', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(T4596).waitForInit();
const record = await mockRecord('collectionA', 2);
await nocoPage.goto();
await page
.getByLabel('block-item-CollectionField-collectionA-form-collectionA.collectionAM2OField-')
.getByTestId('select-object-single')
.click();
await page.getByRole('option', { name: record.collectionAM2OField.id, exact: true }).click();
await expect(
page
.getByLabel('block-item-CollectionField-collectionA-form-collectionA.collectionAM2OField.')
.getByText(record.collectionAM2OField.collectionBM2OField.singleLineText),
).toBeVisible();
});
});

View File

@ -9908,3 +9908,245 @@ export const expressionTemplateInLinkageRules = {
'x-index': 1,
},
};
export const T4596 = {
collections: [
{
name: 'collectionC',
fields: [
{
interface: 'input',
name: 'singleLineText',
},
],
},
{
name: 'collectionB',
fields: [
{
name: 'collectionBM2OField',
interface: 'm2o',
target: 'collectionC',
sourceKey: 'sourceKey',
},
{
name: 'sourceKey',
interface: 'number',
},
],
},
{
name: 'collectionA',
fields: [
{
name: 'collectionAM2OField',
interface: 'm2o',
target: 'collectionB',
},
],
},
],
pageSchema: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Page',
'x-index': 1,
properties: {
'8fabihs13u3': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'page:addBlock',
'x-index': 1,
properties: {
'3nbfdp98hnv': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Row',
'x-app-version': '1.2.4-alpha',
'x-index': 1,
properties: {
e0hd016jask: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Col',
'x-app-version': '1.2.4-alpha',
'x-index': 1,
properties: {
'1pmxkzimdau': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-acl-action-props': {
skipScopeCheck: true,
},
'x-acl-action': 'collectionA:create',
'x-decorator': 'FormBlockProvider',
'x-use-decorator-props': 'useCreateFormBlockDecoratorProps',
'x-decorator-props': {
dataSource: 'main',
collection: 'collectionA',
},
'x-toolbar': 'BlockSchemaToolbar',
'x-settings': 'blockSettings:createForm',
'x-component': 'CardItem',
'x-app-version': '1.2.4-alpha',
'x-index': 1,
properties: {
'3nbd62urdzh': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'FormV2',
'x-use-component-props': 'useCreateFormBlockProps',
'x-app-version': '1.2.4-alpha',
'x-index': 1,
properties: {
grid: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid',
'x-initializer': 'form:configureFields',
'x-app-version': '1.2.4-alpha',
'x-index': 1,
properties: {
'2ljkh36y6n7': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Row',
'x-app-version': '1.2.4-alpha',
'x-index': 1,
properties: {
seg282crfdx: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Col',
'x-app-version': '1.2.4-alpha',
'x-index': 1,
properties: {
collectionAM2OField: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'string',
'x-toolbar': 'FormItemSchemaToolbar',
'x-settings': 'fieldSettings:FormItem',
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-collection-field': 'collectionA.collectionAM2OField',
'x-component-props': {
fieldNames: {
label: 'id',
value: 'id',
},
},
'x-app-version': '1.2.4-alpha',
'x-index': 1,
'x-uid': 'do4yzr3scts',
'x-async': false,
},
},
'x-uid': 'f5omerdi0kn',
'x-async': false,
},
},
'x-uid': '1vxr8iqbc1m',
'x-async': false,
},
'8ez1aq0wv99': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Row',
'x-app-version': '1.2.4-alpha',
'x-index': 2,
properties: {
qxh5iov1310: {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-component': 'Grid.Col',
'x-app-version': '1.2.4-alpha',
'x-index': 1,
properties: {
'collectionAM2OField.collectionBM2OField': {
'x-uid': 'xm0dkxh1m8o',
_isJSONSchemaObject: true,
version: '2.0',
type: 'string',
'x-toolbar': 'FormItemSchemaToolbar',
'x-settings': 'fieldSettings:FormItem',
'x-component': 'CollectionField',
'x-read-pretty': true,
'x-component-props': {
'pattern-disable': true,
fieldNames: {
label: 'singleLineText',
value: 'id',
},
},
'x-decorator': 'FormItem',
'x-collection-field': 'collectionA.collectionAM2OField.collectionBM2OField',
'x-app-version': '1.2.4-alpha',
'x-index': 1,
'x-async': false,
},
},
'x-uid': '34edcrftixd',
'x-async': false,
},
},
'x-uid': 'ewykrxx0ln4',
'x-async': false,
},
},
'x-uid': 'wnea81u7ir5',
'x-async': false,
},
'2kbvvxyxgzj': {
_isJSONSchemaObject: true,
version: '2.0',
type: 'void',
'x-initializer': 'createForm:configureActions',
'x-component': 'ActionBar',
'x-component-props': {
layout: 'one-column',
style: {
marginTop: 'var(--nb-spacing)',
},
},
'x-app-version': '1.2.4-alpha',
'x-index': 2,
'x-uid': '0hstjjkvw9x',
'x-async': false,
},
},
'x-uid': 'qsxevezydxa',
'x-async': false,
},
},
'x-uid': 'zh9641pt4ws',
'x-async': false,
},
},
'x-uid': 'ps0spq4ya0k',
'x-async': false,
},
},
'x-uid': 'uy0bksjg6qk',
'x-async': false,
},
},
'x-uid': 'l5nc16o4pi5',
'x-async': false,
},
},
'x-uid': 'oqkl5enxwq1',
'x-async': true,
},
};

View File

@ -52,7 +52,7 @@ const getFieldPath = (variablePath: string, variablesStore: Record<string, Varia
const VariablesProvider = ({ children }) => {
const ctxRef = useRef<Record<string, any>>({});
const api = useAPIClient();
const { getCollectionJoinField } = useCollectionManager_deprecated();
const { getCollectionJoinField, getCollection } = useCollectionManager_deprecated();
const compile = useCompile();
const { builtinVariables } = useBuiltInVariables();
@ -97,11 +97,14 @@ const VariablesProvider = ({ children }) => {
const key = list[index];
const { fieldPath } = getFieldPath(list.slice(0, index + 1).join('.'), _variableToCollectionName);
const associationField: CollectionFieldOptions_deprecated = getCollectionJoinField(fieldPath, dataSource);
const collectionPrimaryKey = getCollection(collectionName)?.getPrimaryKey();
if (Array.isArray(current)) {
const result = current.map((item) => {
if (shouldToRequest(item?.[key]) && item?.id != null) {
if (shouldToRequest(item?.[key]) && item?.[collectionPrimaryKey] != null) {
if (associationField?.target) {
const url = `/${collectionName}/${item.id}/${key}:${getAction(associationField.type)}`;
const url = `/${collectionName}/${
item[associationField.sourceKey || collectionPrimaryKey]
}/${key}:${getAction(associationField.type)}`;
if (hasRequested(url)) {
return getRequested(url);
}
@ -125,8 +128,10 @@ const VariablesProvider = ({ children }) => {
return item?.[key];
});
current = removeThroughCollectionFields(_.flatten(await Promise.all(result)), associationField);
} else if (shouldToRequest(current[key]) && current.id != null && associationField?.target) {
const url = `/${collectionName}/${current.id}/${key}:${getAction(associationField.type)}`;
} else if (shouldToRequest(current[key]) && current[collectionPrimaryKey] != null && associationField?.target) {
const url = `/${collectionName}/${
current[associationField.sourceKey || collectionPrimaryKey]
}/${key}:${getAction(associationField.type)}`;
let data = null;
if (hasRequested(url)) {
data = await getRequested(url);

View File

@ -66,6 +66,11 @@ vi.mock('../../collection-manager', async () => {
};
}
},
getCollection: () => {
return {
getPrimaryKey: () => 'id',
};
},
};
},
CollectionManagerPane: null,