diff --git a/src/app/shared/menu/menu.service.spec.ts b/src/app/shared/menu/menu.service.spec.ts index 7a6b304ec1..26f32b64ef 100644 --- a/src/app/shared/menu/menu.service.spec.ts +++ b/src/app/shared/menu/menu.service.spec.ts @@ -243,6 +243,84 @@ describe('MenuService', () => { }); }); + describe('isMenuVisibleWithVisibleSections', () => { + it('should return false when the menu is empty', () => { + const fakeMenu = { + id: MenuID.ADMIN, + collapsed: false, + visible: true, + sections: {}, + previewCollapsed: false, + sectionToSubsectionIndex: {} + } as any; + spyOn(service, 'getMenu').and.returnValue(observableOf(fakeMenu)); + + const result = service.isMenuVisibleWithVisibleSections(MenuID.ADMIN); + const expected = cold('(b|)', { + b: false + }); + + expect(result).toBeObservable(expected); + }); + it('should return false when no top-level sections are visible', () => { + const noTopLevelVisibleSections = { + section: {id: 's1', visible: false}, + section_2: {id: 's2', visible: false}, + section_3: {id: 's3', visible: false}, + section_4: {id: 's1_1', visible: true, parentID: 's1'}, + section_5: {id: 's2_1', visible: true, parentID: 's2'}, + } + const fakeMenu = { + id: MenuID.ADMIN, + collapsed: false, + visible: true, + sections: noTopLevelVisibleSections, + previewCollapsed: false, + sectionToSubsectionIndex: { + 'section': ['section_4'], + 'section_2': ['section_5'], + } + } as any; + spyOn(service, 'getMenu').and.returnValue(observableOf(fakeMenu)); + + const result = service.isMenuVisibleWithVisibleSections(MenuID.ADMIN); + const expected = cold('(b|)', { + b: false + }); + + expect(result).toBeObservable(expected); + }); + + it('should return true when any top-level section is visible', () => { + const noTopLevelVisibleSections = { + section: {id: 's1', visible: false}, + section_2: {id: 's2', visible: true}, + section_3: {id: 's3', visible: false}, + section_4: {id: 's1_1', visible: true, parentID: 's1'}, + section_5: {id: 's2_1', visible: true, parentID: 's2'}, + } + const fakeMenu = { + id: MenuID.ADMIN, + collapsed: false, + visible: true, + sections: noTopLevelVisibleSections, + previewCollapsed: false, + sectionToSubsectionIndex: { + 'section': ['section_4'], + 'section_2': ['section_5'], + } + } as any; + spyOn(service, 'getMenu').and.returnValue(observableOf(fakeMenu)); + + const result = service.isMenuVisibleWithVisibleSections(MenuID.ADMIN); + const expected = cold('(b|)', { + b: true + }); + + expect(result).toBeObservable(expected); + }); + }); + describe('isMenuVisible', () => { beforeEach(() => { spyOn(service, 'getMenu').and.returnValue(observableOf(fakeMenu)); diff --git a/src/app/shared/menu/menu.service.ts b/src/app/shared/menu/menu.service.ts index ab513fbbdf..8e2cb8a894 100644 --- a/src/app/shared/menu/menu.service.ts +++ b/src/app/shared/menu/menu.service.ts @@ -182,7 +182,7 @@ export class MenuService { } /** - * Check if a given menu is visible and has visible sections + * Check if a given menu is visible and has visible top-level (!) sections * @param {MenuID} menuID The ID of the menu that is to be checked * @returns {Observable} Emits true if the given menu is * visible and has visible sections, emits false when it's hidden @@ -205,14 +205,16 @@ export class MenuService { } /** - * Check if a menu has at least one section that is visible. + * Check if a menu has at least one top-level (!) section that is visible. * @param {MenuID} menuID The ID of the menu that is to be checked * @returns {Observable} Emits true if the given menu has visible sections, emits false otherwise */ menuHasVisibleSections(menuID: MenuID): Observable { return this.getMenu(menuID).pipe( map((state: MenuState) => hasValue(state) - ? Object.values(state.sections).map(section => section.visible).reduce((x,y) => x || y, false) + ? Object.values(state.sections) + .map(section => section.visible && section.parentID === undefined) + .reduce((x,y) => x || y, false) : undefined) ); }