From 8d8105a20566917b234614f39770721e569f1831 Mon Sep 17 00:00:00 2001 From: chenos Date: Tue, 2 Jul 2024 10:59:54 +0800 Subject: [PATCH] fix(popups): correct value for filterByTk (#4792) * feat: add CollectionManager.getFilterByTk method * refactor: optimize and add tests * fix: use correct filterByTK value --------- Co-authored-by: Zeke Zhang <958414905@qq.com> --- .../collection/CollectionManager.test.tsx | 22 +++++++- .../collection/CollectionManager.ts | 51 +++++++++++++++++++ .../schema-component/antd/page/SubPages.tsx | 9 ++-- .../antd/page/pagePopupUtils.tsx | 16 +++--- 4 files changed, 84 insertions(+), 14 deletions(-) diff --git a/packages/core/client/src/data-source/__tests__/collection/CollectionManager.test.tsx b/packages/core/client/src/data-source/__tests__/collection/CollectionManager.test.tsx index c55f68fb0f..33b591c81a 100644 --- a/packages/core/client/src/data-source/__tests__/collection/CollectionManager.test.tsx +++ b/packages/core/client/src/data-source/__tests__/collection/CollectionManager.test.tsx @@ -7,7 +7,7 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { Application, CollectionManager, CollectionTemplate, Collection } from '@nocobase/client'; +import { Application, Collection, CollectionManager, CollectionTemplate } from '@nocobase/client'; import collections from '../collections.json'; describe('CollectionManager', () => { @@ -301,5 +301,25 @@ describe('CollectionManager', () => { expect(result).toBe('id'); }); }); + + describe('getFilterByTK', () => { + it('should return the value of the filterByTK', () => { + const result = collectionManager.getFilterByTK('users', { id: 1 }); + expect(result).toBe(1); + + const result2 = collectionManager.getFilterByTK('users.roles', { name: 'rolesName' }); + expect(result2).toBe('rolesName'); + }); + + it('should return undefined when collectionOrAssociation is not provided', () => { + const result = collectionManager.getFilterByTK('', { id: 1 }); + expect(result).toBeUndefined(); + }); + + it('should return undefined when collectionOrAssociation is invalid', () => { + const result = collectionManager.getFilterByTK('uses.invalid', { id: 1 }); + expect(result).toBeUndefined(); + }); + }); }); }); diff --git a/packages/core/client/src/data-source/collection/CollectionManager.ts b/packages/core/client/src/data-source/collection/CollectionManager.ts index 398f53a10a..0d9265973f 100644 --- a/packages/core/client/src/data-source/collection/CollectionManager.ts +++ b/packages/core/client/src/data-source/collection/CollectionManager.ts @@ -140,6 +140,57 @@ export class CollectionManager { return this.getCollection(collectionName)?.getFields(predicate) || []; } + /** + * @example + * getFilterByTK('users', { id: 1 }); // 1 + * getFilterByTK('users.profile', { name: 'name' }); // name + * + * @param collectionOrAssociation - collection name or association name + * @param collectionRecordOrAssociationRecord - collection record or association record + * @returns the value of the filterByTK + */ + getFilterByTK( + collectionOrAssociation: string | Collection, + collectionRecordOrAssociationRecord: Record, + ) { + if (!collectionOrAssociation || !collectionRecordOrAssociationRecord) { + console.error( + '@nocobase/client]: CollectionManager.getFilterByTK() collectionOrAssociation or collectionRecordOrAssociationRecord is invalid', + ); + return; + } + + if (collectionOrAssociation instanceof Collection) { + const key = collectionOrAssociation.filterTargetKey || collectionOrAssociation.getPrimaryKey() || 'id'; + return collectionRecordOrAssociationRecord[key]; + } + + if (collectionOrAssociation.includes('.')) { + const field = this.getCollectionField(collectionOrAssociation); + // 字段不存在,返回空 + if (!field) { + console.error( + `[@nocobase/client]: CollectionManager.getFilterByTK() field "${collectionOrAssociation}" is invalid`, + ); + return; + } + if (field.targetKey) { + return collectionRecordOrAssociationRecord[field.targetKey]; + } + } + const targetCollection = this.getCollection(collectionOrAssociation); + + if (!targetCollection) { + console.error( + `[@nocobase/client]: CollectionManager.getFilterByTK() collection "${collectionOrAssociation}" is invalid`, + ); + return; + } + + const key = targetCollection?.filterTargetKey || targetCollection?.getPrimaryKey() || 'id'; + return collectionRecordOrAssociationRecord[key]; + } + getSourceKeyByAssociation(associationName: string) { if (!associationName) { return; diff --git a/packages/core/client/src/schema-component/antd/page/SubPages.tsx b/packages/core/client/src/schema-component/antd/page/SubPages.tsx index 567baed7e6..b23b1f6c43 100644 --- a/packages/core/client/src/schema-component/antd/page/SubPages.tsx +++ b/packages/core/client/src/schema-component/antd/page/SubPages.tsx @@ -212,8 +212,8 @@ export const useNavigateTOSubPage = () => { return setVisibleFromAction?.(true); } - const filterByTK = (record?.data || treeParentRecord)?.[collection.getPrimaryKey()]; - const sourceId = parentRecord?.data?.[cm.getCollection(association?.split('.')[0])?.getPrimaryKey()]; + const filterByTK = cm.getFilterByTK(association || collection, record?.data || treeParentRecord); + const sourceId = parentRecord?.data?.[cm.getSourceKeyByAssociation(association)]; const params: SubPageParams = { subpageuid: fieldSchema['x-uid'], filterbytk: filterByTK, @@ -231,8 +231,9 @@ export const useNavigateTOSubPage = () => { sourceId, parentPopupRecord: parentPopupRecordData ? { + // TODO: 这里应该需要 association 的 值 collection: parentPopupRecordCollection?.name, - filterByTk: parentPopupRecordData[parentPopupRecordCollection.getPrimaryKey()], + filterByTk: cm.getFilterByTK(parentPopupRecordCollection, parentPopupRecordData), } : undefined, }); @@ -244,7 +245,7 @@ export const useNavigateTOSubPage = () => { parentPopupRecord: parentPopupRecordData ? { collection: parentPopupRecordCollection?.name, - filterByTk: parentPopupRecordData[parentPopupRecordCollection.getPrimaryKey()], + filterByTk: cm.getFilterByTK(parentPopupRecordCollection, parentPopupRecordData), } : undefined, }); diff --git a/packages/core/client/src/schema-component/antd/page/pagePopupUtils.tsx b/packages/core/client/src/schema-component/antd/page/pagePopupUtils.tsx index e506326ce3..db947212a4 100644 --- a/packages/core/client/src/schema-component/antd/page/pagePopupUtils.tsx +++ b/packages/core/client/src/schema-component/antd/page/pagePopupUtils.tsx @@ -108,7 +108,7 @@ export const usePagePopup = () => { const { value: parentPopupRecordData, collection: parentPopupRecordCollection } = useCurrentPopupRecord() || {}; const getSourceId = useCallback( (_parentRecordData?: Record) => - (_parentRecordData || parentRecord?.data)?.[cm.getCollection(association?.split('.')[0])?.getPrimaryKey()], + (_parentRecordData || parentRecord?.data)?.[cm.getSourceKeyByAssociation(association)], [parentRecord, association], ); @@ -124,11 +124,7 @@ export const usePagePopup = () => { sourceId: string; tabKey?: string; }) => { - let _collection = collection; - if (association) { - _collection = cm.getCollection(association); - } - const filterByTK = recordData?.[_collection.getPrimaryKey()]; + const filterByTK = cm.getFilterByTK(association || collection, recordData); return getPopupPathFromParams({ popupuid: popupUid, filterbytk: filterByTK, @@ -146,14 +142,15 @@ export const usePagePopup = () => { association, parentPopupRecord: !_.isEmpty(parentPopupRecordData) ? { + // TODO: 这里应该需要 association 的 值 collection: parentPopupRecordCollection?.name, - filterByTk: parentPopupRecordData[parentPopupRecordCollection.getPrimaryKey()], + filterByTk: cm.getFilterByTK(parentPopupRecordCollection, parentPopupRecordData), } : undefined, }; return _.omitBy(context, _.isNil) as PopupContext; - }, [dataSourceKey, collection, association, parentPopupRecordData, parentPopupRecordCollection]); + }, [dataSourceKey, collection, association, parentPopupRecordData, parentPopupRecordCollection, cm]); const openPopup = useCallback( ({ @@ -187,8 +184,9 @@ export const usePagePopup = () => { sourceId, parentPopupRecord: parentPopupRecordData ? { + // TODO: 这里应该需要 association 的 值 collection: parentPopupRecordCollection?.name, - filterByTk: parentPopupRecordData[parentPopupRecordCollection.getPrimaryKey()], + filterByTk: cm.getFilterByTK(parentPopupRecordCollection, parentPopupRecordData), } : undefined, });