mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-02 11:12:20 +08:00
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:
parent
ac472efd23
commit
6e0074fb66
@ -13,7 +13,7 @@ import {
|
|||||||
oneSubformWithMultiLevelAssociationFields,
|
oneSubformWithMultiLevelAssociationFields,
|
||||||
test,
|
test,
|
||||||
} from '@nocobase/test/e2e';
|
} 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.describe('display association fields', () => {
|
||||||
test('form: should display correctly', async ({ page, mockPage, mockRecord }) => {
|
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),
|
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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -9908,3 +9908,245 @@ export const expressionTemplateInLinkageRules = {
|
|||||||
'x-index': 1,
|
'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,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
@ -52,7 +52,7 @@ const getFieldPath = (variablePath: string, variablesStore: Record<string, Varia
|
|||||||
const VariablesProvider = ({ children }) => {
|
const VariablesProvider = ({ children }) => {
|
||||||
const ctxRef = useRef<Record<string, any>>({});
|
const ctxRef = useRef<Record<string, any>>({});
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
const { getCollectionJoinField } = useCollectionManager_deprecated();
|
const { getCollectionJoinField, getCollection } = useCollectionManager_deprecated();
|
||||||
const compile = useCompile();
|
const compile = useCompile();
|
||||||
const { builtinVariables } = useBuiltInVariables();
|
const { builtinVariables } = useBuiltInVariables();
|
||||||
|
|
||||||
@ -97,11 +97,14 @@ const VariablesProvider = ({ children }) => {
|
|||||||
const key = list[index];
|
const key = list[index];
|
||||||
const { fieldPath } = getFieldPath(list.slice(0, index + 1).join('.'), _variableToCollectionName);
|
const { fieldPath } = getFieldPath(list.slice(0, index + 1).join('.'), _variableToCollectionName);
|
||||||
const associationField: CollectionFieldOptions_deprecated = getCollectionJoinField(fieldPath, dataSource);
|
const associationField: CollectionFieldOptions_deprecated = getCollectionJoinField(fieldPath, dataSource);
|
||||||
|
const collectionPrimaryKey = getCollection(collectionName)?.getPrimaryKey();
|
||||||
if (Array.isArray(current)) {
|
if (Array.isArray(current)) {
|
||||||
const result = current.map((item) => {
|
const result = current.map((item) => {
|
||||||
if (shouldToRequest(item?.[key]) && item?.id != null) {
|
if (shouldToRequest(item?.[key]) && item?.[collectionPrimaryKey] != null) {
|
||||||
if (associationField?.target) {
|
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)) {
|
if (hasRequested(url)) {
|
||||||
return getRequested(url);
|
return getRequested(url);
|
||||||
}
|
}
|
||||||
@ -125,8 +128,10 @@ const VariablesProvider = ({ children }) => {
|
|||||||
return item?.[key];
|
return item?.[key];
|
||||||
});
|
});
|
||||||
current = removeThroughCollectionFields(_.flatten(await Promise.all(result)), associationField);
|
current = removeThroughCollectionFields(_.flatten(await Promise.all(result)), associationField);
|
||||||
} else if (shouldToRequest(current[key]) && current.id != null && associationField?.target) {
|
} else if (shouldToRequest(current[key]) && current[collectionPrimaryKey] != null && associationField?.target) {
|
||||||
const url = `/${collectionName}/${current.id}/${key}:${getAction(associationField.type)}`;
|
const url = `/${collectionName}/${
|
||||||
|
current[associationField.sourceKey || collectionPrimaryKey]
|
||||||
|
}/${key}:${getAction(associationField.type)}`;
|
||||||
let data = null;
|
let data = null;
|
||||||
if (hasRequested(url)) {
|
if (hasRequested(url)) {
|
||||||
data = await getRequested(url);
|
data = await getRequested(url);
|
||||||
|
@ -66,6 +66,11 @@ vi.mock('../../collection-manager', async () => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getCollection: () => {
|
||||||
|
return {
|
||||||
|
getPrimaryKey: () => 'id',
|
||||||
|
};
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
CollectionManagerPane: null,
|
CollectionManagerPane: null,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user