diff --git a/src/app/admin/admin-sidebar/admin-sidebar.component.ts b/src/app/admin/admin-sidebar/admin-sidebar.component.ts index 8eb288daa2..36f9250504 100644 --- a/src/app/admin/admin-sidebar/admin-sidebar.component.ts +++ b/src/app/admin/admin-sidebar/admin-sidebar.component.ts @@ -100,6 +100,7 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit { } } }); + this.menuVisible = this.menuService.isMenuVisibleWithVisibleSections(this.menuID); } @HostListener('focusin') diff --git a/src/app/core/data/feature-authorization/feature-id.ts b/src/app/core/data/feature-authorization/feature-id.ts index 3cb18bf515..9e73ca9a2b 100644 --- a/src/app/core/data/feature-authorization/feature-id.ts +++ b/src/app/core/data/feature-authorization/feature-id.ts @@ -29,5 +29,7 @@ export enum FeatureID { CanViewUsageStatistics = 'canViewUsageStatistics', CanSendFeedback = 'canSendFeedback', CanClaimItem = 'canClaimItem', - CanSynchronizeWithORCID = 'canSynchronizeWithORCID' + CanSynchronizeWithORCID = 'canSynchronizeWithORCID', + CanSubmit = 'canSubmit', + CanEditItem = 'canEditItem', } diff --git a/src/app/menu.resolver.ts b/src/app/menu.resolver.ts index 60f2d1cca2..19413ab4be 100644 --- a/src/app/menu.resolver.ts +++ b/src/app/menu.resolver.ts @@ -167,10 +167,11 @@ export class MenuResolver implements Resolve { combineLatest([ this.authorizationService.isAuthorized(FeatureID.IsCollectionAdmin), this.authorizationService.isAuthorized(FeatureID.IsCommunityAdmin), - this.authorizationService.isAuthorized(FeatureID.AdministratorOf) - ]).subscribe(([isCollectionAdmin, isCommunityAdmin, isSiteAdmin]) => { - const menuList = [ - /* News */ + this.authorizationService.isAuthorized(FeatureID.AdministratorOf), + this.authorizationService.isAuthorized(FeatureID.CanSubmit), + this.authorizationService.isAuthorized(FeatureID.CanEditItem), + ]).subscribe(([isCollectionAdmin, isCommunityAdmin, isSiteAdmin, canSubmit, canEditItem]) => { + const newSubMenuList = [ { id: 'new_community', parentID: 'new', @@ -201,7 +202,7 @@ export class MenuResolver implements Resolve { id: 'new_item', parentID: 'new', active: false, - visible: true, + visible: canSubmit, model: { type: MenuItemType.ONCLICK, text: 'menu.section.new_item', @@ -221,30 +222,8 @@ export class MenuResolver implements Resolve { link: '/processes/new' } as LinkMenuItemModel, }, - { - id: 'new', - active: false, - visible: true, - model: { - type: MenuItemType.TEXT, - text: 'menu.section.new' - } as TextMenuItemModel, - icon: 'plus', - index: 0 - }, - // TODO: enable this menu item once the feature has been implemented - // { - // id: 'new_item_version', - // parentID: 'new', - // active: false, - // visible: true, - // model: { - // type: MenuItemType.LINK, - // text: 'menu.section.new_item_version', - // link: '' - // } as LinkMenuItemModel, - // }, - + ]; + const editSubMenuList = [ /* Edit */ { id: 'edit_community', @@ -276,7 +255,7 @@ export class MenuResolver implements Resolve { id: 'edit_item', parentID: 'edit', active: false, - visible: true, + visible: canEditItem, model: { type: MenuItemType.ONCLICK, text: 'menu.section.edit_item', @@ -285,17 +264,47 @@ export class MenuResolver implements Resolve { } } as OnClickMenuItemModel, }, - { - id: 'edit', - active: false, - visible: true, - model: { - type: MenuItemType.TEXT, - text: 'menu.section.edit' - } as TextMenuItemModel, - icon: 'pencil-alt', - index: 1 - }, + ]; + const newSubMenu = { + id: 'new', + active: false, + visible: newSubMenuList.map(subMenu => subMenu.visible).reduce((x,y) => x || y), + model: { + type: MenuItemType.TEXT, + text: 'menu.section.new' + } as TextMenuItemModel, + icon: 'plus', + index: 0 + } + const editSubMenu = { + id: 'edit', + active: false, + visible: editSubMenuList.map(subMenu => subMenu.visible).reduce((x,y) => x || y), + model: { + type: MenuItemType.TEXT, + text: 'menu.section.edit' + } as TextMenuItemModel, + icon: 'pencil-alt', + index: 1 + } + + const menuList = [ + ...newSubMenuList, + newSubMenu, + ...editSubMenuList, + editSubMenu, + // TODO: enable this menu item once the feature has been implemented + // { + // id: 'new_item_version', + // parentID: 'new', + // active: false, + // visible: true, + // model: { + // type: MenuItemType.LINK, + // text: 'menu.section.new_item_version', + // link: '' + // } as LinkMenuItemModel, + // }, /* Statistics */ // TODO: enable this menu item once the feature has been implemented diff --git a/src/app/root/root.component.ts b/src/app/root/root.component.ts index 472ba440c9..c265cec034 100644 --- a/src/app/root/root.component.ts +++ b/src/app/root/root.component.ts @@ -61,7 +61,7 @@ export class RootComponent implements OnInit { } ngOnInit() { - this.sidebarVisible = this.menuService.isMenuVisible(MenuID.ADMIN); + this.sidebarVisible = this.menuService.isMenuVisibleWithVisibleSections(MenuID.ADMIN); this.collapsedSidebarWidth = this.cssService.getVariable('collapsedSidebarWidth'); this.totalSidebarWidth = this.cssService.getVariable('totalSidebarWidth'); diff --git a/src/app/shared/menu/menu.service.ts b/src/app/shared/menu/menu.service.ts index f44ddea649..ab513fbbdf 100644 --- a/src/app/shared/menu/menu.service.ts +++ b/src/app/shared/menu/menu.service.ts @@ -181,6 +181,18 @@ export class MenuService { ); } + /** + * Check if a given menu is visible and has visible 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 + */ + isMenuVisibleWithVisibleSections(menuID: MenuID): Observable { + return observableCombineLatest([this.isMenuVisible(menuID), this.menuHasVisibleSections(menuID)]).pipe( + map(([menuVisible, visibleSections]) => menuVisible && visibleSections) + ); + } + /** * Check if a given menu is visible * @param {MenuID} menuID The ID of the menu that is to be checked @@ -192,6 +204,19 @@ export class MenuService { ); } + /** + * Check if a menu has at least one 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) + : undefined) + ); + } + /** * Expands a given menu * @param {MenuID} menuID The ID of the menu