From f64b241d3248677d100efd38751d0daddc892f19 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Mon, 1 Aug 2022 14:47:52 +0100 Subject: [PATCH] Navigation: split logic, reenable unit test, copy whole node to prevent recursion error (#53033) * split logic, reenable unit test, copy whole node to prevent recursion error * remove double assignment --- public/app/core/selectors/navModel.test.ts | 3 +- public/app/core/selectors/navModel.ts | 42 ++++++++++++---------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/public/app/core/selectors/navModel.test.ts b/public/app/core/selectors/navModel.test.ts index f95fc1afa34..951bc5fa3e0 100644 --- a/public/app/core/selectors/navModel.test.ts +++ b/public/app/core/selectors/navModel.test.ts @@ -42,8 +42,7 @@ describe('getNavModel', () => { expect(navModel.node.parentItem?.id).toBe(navModel.main.id); }); - // TODO reenable this test once we figure out the logic for 2nd level children - test.skip('returns the correct nav model for a 2nd-level child', () => { + test('returns the correct nav model for a 2nd-level child', () => { const navModel = getNavModel(navIndex, 'apps/subapp/child1'); expect(navModel.main.id).toBe('apps'); expect(navModel.node.id).toBe('apps/subapp/child1'); diff --git a/public/app/core/selectors/navModel.ts b/public/app/core/selectors/navModel.ts index a4808559203..db34a8125d4 100644 --- a/public/app/core/selectors/navModel.ts +++ b/public/app/core/selectors/navModel.ts @@ -18,10 +18,11 @@ const getNotFoundModel = (): NavModel => { export const getNavModel = (navIndex: NavIndex, id: string, fallback?: NavModel, onlyChild = false): NavModel => { if (navIndex[id]) { const node = navIndex[id]; - const main = onlyChild ? node : getSectionRoot(node); + const nodeWithActive = enrichNodeWithActiveState(node); + const main = onlyChild ? nodeWithActive : getSectionRoot(nodeWithActive); return { - node, + node: nodeWithActive, main, }; } @@ -34,23 +35,28 @@ export const getNavModel = (navIndex: NavIndex, id: string, fallback?: NavModel, }; function getSectionRoot(node: NavModelItem): NavModelItem { - if (!node.parentItem) { - return node; + return node.parentItem ? getSectionRoot(node.parentItem) : node; +} + +function enrichNodeWithActiveState(node: NavModelItem): NavModelItem { + const nodeCopy = { ...node }; + if (nodeCopy.parentItem) { + nodeCopy.parentItem = { ...nodeCopy.parentItem }; + const root = nodeCopy.parentItem; + + if (root.children) { + root.children = root.children.map((item) => { + if (item.id === node.id) { + return { ...nodeCopy, active: true }; + } + + return item; + }); + } + + nodeCopy.parentItem = enrichNodeWithActiveState(root); } - - const root = (node.parentItem = { ...node.parentItem }); - - if (root.children) { - root.children = root.children.map((item) => { - if (item.id === node.id) { - return { ...item, active: true }; - } - - return item; - }); - } - - return getSectionRoot(root); + return nodeCopy; } export const getTitleFromNavModel = (navModel: NavModel) => {