From aae75de70b79b0dd6243fceacc3a4e463fdc6fb0 Mon Sep 17 00:00:00 2001 From: YANG QIA <2013xile@gmail.com> Date: Tue, 11 Jun 2024 11:34:11 +0800 Subject: [PATCH] feat(tree-block): support filtering child nodes (#4603) * feat(tree-block): support filtering child nodes * test: add list test * test: remove only * fix: use isValidFilter --- .../actions/src/__tests__/list-action.test.ts | 84 +++++++++++++++++++ packages/core/actions/src/actions/list.ts | 18 ++-- .../src/default-actions/list.ts | 16 ++-- 3 files changed, 105 insertions(+), 13 deletions(-) diff --git a/packages/core/actions/src/__tests__/list-action.test.ts b/packages/core/actions/src/__tests__/list-action.test.ts index 0a3521b605..92d84fd462 100644 --- a/packages/core/actions/src/__tests__/list-action.test.ts +++ b/packages/core/actions/src/__tests__/list-action.test.ts @@ -344,4 +344,88 @@ describe('list-tree', () => { expect(response.status).toEqual(200); expect(response.body.rows).toMatchObject(values); }); + + it('should filter child nodes for tree', async () => { + const values = [ + { + name: 'A1', + __index: '0', + children3: [ + { + name: 'B', + __index: '0.children3.0', + children3: [ + { + name: 'C', + __index: '0.children3.0.children3.0', + }, + ], + }, + ], + }, + { + name: 'A2', + __index: '1', + children3: [ + { + name: 'B', + __index: '1.children3.0', + }, + ], + }, + ]; + + const db = app.db; + db.collection({ + name: 'categories', + tree: 'adjacency-list', + fields: [ + { + type: 'string', + name: 'name', + }, + { + type: 'string', + name: 'description', + }, + { + type: 'belongsTo', + name: 'parent', + foreignKey: 'cid', + treeParent: true, + }, + { + type: 'hasMany', + name: 'children3', + foreignKey: 'cid', + treeChildren: true, + }, + ], + }); + await db.sync(); + + await db.getRepository('categories').create({ + values, + }); + + const response = await app + .agent() + .resource('categories') + .list({ + tree: true, + fields: ['id', 'name'], + appends: ['parent'], + filter: { + name: 'B', + }, + }); + + expect(response.status).toEqual(200); + const rows = response.body.rows; + expect(rows.length).toEqual(2); + expect(rows[0].name).toEqual('B'); + expect(rows[1].name).toEqual('B'); + expect(rows[0].parent.name).toEqual('A1'); + expect(rows[1].parent.name).toEqual('A2'); + }); }); diff --git a/packages/core/actions/src/actions/list.ts b/packages/core/actions/src/actions/list.ts index efb5745759..570b4950fa 100644 --- a/packages/core/actions/src/actions/list.ts +++ b/packages/core/actions/src/actions/list.ts @@ -7,7 +7,7 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { assign } from '@nocobase/utils'; +import { assign, isValidFilter } from '@nocobase/utils'; import { Context } from '..'; import { getRepositoryFromParams, pageArgsToLimitArgs } from '../utils'; import { DEFAULT_PAGE, DEFAULT_PER_PAGE } from '../constants'; @@ -20,12 +20,16 @@ function findArgs(ctx: Context) { const resourceName = ctx.action.resourceName; const params = ctx.action.params; if (params.tree) { - const [collectionName, associationName] = resourceName.split('.'); - const collection = ctx.db.getCollection(resourceName); - // tree collection 或者关系表是 tree collection - if (collection.options.tree && !(associationName && collectionName === collection.name)) { - const foreignKey = collection.treeParentField?.foreignKey || 'parentId'; - assign(params, { filter: { [foreignKey]: null } }, { filter: 'andMerge' }); + if (isValidFilter(params.filter)) { + params.tree = false; + } else { + const [collectionName, associationName] = resourceName.split('.'); + const collection = ctx.db.getCollection(resourceName); + // tree collection 或者关系表是 tree collection + if (collection.options.tree && !(associationName && collectionName === collection.name)) { + const foreignKey = collection.treeParentField?.foreignKey || 'parentId'; + assign(params, { filter: { [foreignKey]: null } }, { filter: 'andMerge' }); + } } } const { tree, fields, filter, appends, except, sort } = params; diff --git a/packages/core/data-source-manager/src/default-actions/list.ts b/packages/core/data-source-manager/src/default-actions/list.ts index afe0bda75f..e3f73cf870 100644 --- a/packages/core/data-source-manager/src/default-actions/list.ts +++ b/packages/core/data-source-manager/src/default-actions/list.ts @@ -7,7 +7,7 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { assign } from '@nocobase/utils'; +import { assign, isValidFilter } from '@nocobase/utils'; import { pageArgsToLimitArgs } from './utils'; import { Context } from '@nocobase/actions'; @@ -20,11 +20,15 @@ function findArgs(ctx: Context) { const params = ctx.action.params; if (params.tree) { - const [collectionName, associationName] = resourceName.split('.'); - const collection = ctx.db.getCollection(resourceName); - if (collection.options.tree && !(associationName && collectionName === collection.name)) { - const foreignKey = collection.treeParentField?.foreignKey || 'parentId'; - assign(params, { filter: { [foreignKey]: null } }, { filter: 'andMerge' }); + if (isValidFilter(params.filter)) { + params.tree = false; + } else { + const [collectionName, associationName] = resourceName.split('.'); + const collection = ctx.db.getCollection(resourceName); + if (collection.options.tree && !(associationName && collectionName === collection.name)) { + const foreignKey = collection.treeParentField?.foreignKey || 'parentId'; + assign(params, { filter: { [foreignKey]: null } }, { filter: 'andMerge' }); + } } }