mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
90978: Move admin menu to MenuResolver, clean up & add tests
This commit is contained in:
@@ -182,150 +182,4 @@ describe('AdminSidebarComponent', () => {
|
|||||||
expect(menuService.collapseMenuPreview).toHaveBeenCalled();
|
expect(menuService.collapseMenuPreview).toHaveBeenCalled();
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('menu', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
spyOn(menuService, 'addSection');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('for regular user', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake(() => {
|
|
||||||
return observableOf(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
comp.createMenu();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not show site admin section', () => {
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'admin_search', visible: false,
|
|
||||||
}));
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'registries', visible: false,
|
|
||||||
}));
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
parentID: 'registries', visible: false,
|
|
||||||
}));
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'curation_tasks', visible: false,
|
|
||||||
}));
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'workflow', visible: false,
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not show edit_community', () => {
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'edit_community', visible: false,
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not show edit_collection', () => {
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'edit_collection', visible: false,
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not show access control section', () => {
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'access_control', visible: false,
|
|
||||||
}));
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
parentID: 'access_control', visible: false,
|
|
||||||
}));
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('for site admin', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake((featureID: FeatureID) => {
|
|
||||||
return observableOf(featureID === FeatureID.AdministratorOf);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
comp.createMenu();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should contain site admin section', () => {
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'admin_search', visible: true,
|
|
||||||
}));
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'registries', visible: true,
|
|
||||||
}));
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
parentID: 'registries', visible: true,
|
|
||||||
}));
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'curation_tasks', visible: true,
|
|
||||||
}));
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'workflow', visible: true,
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('for community admin', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake((featureID: FeatureID) => {
|
|
||||||
return observableOf(featureID === FeatureID.IsCommunityAdmin);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
comp.createMenu();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show edit_community', () => {
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'edit_community', visible: true,
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('for collection admin', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake((featureID: FeatureID) => {
|
|
||||||
return observableOf(featureID === FeatureID.IsCollectionAdmin);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
comp.createMenu();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show edit_collection', () => {
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'edit_collection', visible: true,
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('for group admin', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake((featureID: FeatureID) => {
|
|
||||||
return observableOf(featureID === FeatureID.CanManageGroups);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
comp.createMenu();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should show access control section', () => {
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
id: 'access_control', visible: true,
|
|
||||||
}));
|
|
||||||
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
|
|
||||||
parentID: 'access_control', visible: true,
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@@ -67,9 +67,7 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
|||||||
protected injector: Injector,
|
protected injector: Injector,
|
||||||
private variableService: CSSVariableService,
|
private variableService: CSSVariableService,
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private modalService: NgbModal,
|
|
||||||
public authorizationService: AuthorizationDataService,
|
public authorizationService: AuthorizationDataService,
|
||||||
private scriptDataService: ScriptDataService,
|
|
||||||
public route: ActivatedRoute
|
public route: ActivatedRoute
|
||||||
) {
|
) {
|
||||||
super(menuService, injector, authorizationService, route);
|
super(menuService, injector, authorizationService, route);
|
||||||
@@ -80,7 +78,6 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
|||||||
* Set and calculate all initial values of the instance variables
|
* Set and calculate all initial values of the instance variables
|
||||||
*/
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.createMenu();
|
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
this.sidebarWidth = this.variableService.getVariable('sidebarItemsWidth');
|
this.sidebarWidth = this.variableService.getVariable('sidebarItemsWidth');
|
||||||
this.authService.isAuthenticated()
|
this.authService.isAuthenticated()
|
||||||
@@ -115,501 +112,6 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize all menu sections and items for this menu
|
|
||||||
*/
|
|
||||||
createMenu() {
|
|
||||||
this.createMainMenuSections();
|
|
||||||
this.createSiteAdministratorMenuSections();
|
|
||||||
this.createExportMenuSections();
|
|
||||||
this.createImportMenuSections();
|
|
||||||
this.createAccessControlMenuSections();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the main menu sections.
|
|
||||||
* edit_community / edit_collection is only included if the current user is a Community or Collection admin
|
|
||||||
*/
|
|
||||||
createMainMenuSections() {
|
|
||||||
combineLatest([
|
|
||||||
this.authorizationService.isAuthorized(FeatureID.IsCollectionAdmin),
|
|
||||||
this.authorizationService.isAuthorized(FeatureID.IsCommunityAdmin),
|
|
||||||
this.authorizationService.isAuthorized(FeatureID.AdministratorOf)
|
|
||||||
]).subscribe(([isCollectionAdmin, isCommunityAdmin, isSiteAdmin]) => {
|
|
||||||
const menuList = [
|
|
||||||
/* News */
|
|
||||||
{
|
|
||||||
id: 'new',
|
|
||||||
active: false,
|
|
||||||
visible: true,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.TEXT,
|
|
||||||
text: 'menu.section.new'
|
|
||||||
} as TextMenuItemModel,
|
|
||||||
icon: 'plus',
|
|
||||||
index: 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'new_community',
|
|
||||||
parentID: 'new',
|
|
||||||
active: false,
|
|
||||||
visible: isCommunityAdmin,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.ONCLICK,
|
|
||||||
text: 'menu.section.new_community',
|
|
||||||
function: () => {
|
|
||||||
this.modalService.open(CreateCommunityParentSelectorComponent);
|
|
||||||
}
|
|
||||||
} as OnClickMenuItemModel,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'new_collection',
|
|
||||||
parentID: 'new',
|
|
||||||
active: false,
|
|
||||||
visible: isCommunityAdmin,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.ONCLICK,
|
|
||||||
text: 'menu.section.new_collection',
|
|
||||||
function: () => {
|
|
||||||
this.modalService.open(CreateCollectionParentSelectorComponent);
|
|
||||||
}
|
|
||||||
} as OnClickMenuItemModel,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'new_item',
|
|
||||||
parentID: 'new',
|
|
||||||
active: false,
|
|
||||||
visible: true,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.ONCLICK,
|
|
||||||
text: 'menu.section.new_item',
|
|
||||||
function: () => {
|
|
||||||
this.modalService.open(CreateItemParentSelectorComponent);
|
|
||||||
}
|
|
||||||
} as OnClickMenuItemModel,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'new_process',
|
|
||||||
parentID: 'new',
|
|
||||||
active: false,
|
|
||||||
visible: isCollectionAdmin,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.LINK,
|
|
||||||
text: 'menu.section.new_process',
|
|
||||||
link: '/processes/new'
|
|
||||||
} as LinkMenuItemModel,
|
|
||||||
},
|
|
||||||
// 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,
|
|
||||||
// },
|
|
||||||
|
|
||||||
/* Edit */
|
|
||||||
{
|
|
||||||
id: 'edit',
|
|
||||||
active: false,
|
|
||||||
visible: true,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.TEXT,
|
|
||||||
text: 'menu.section.edit'
|
|
||||||
} as TextMenuItemModel,
|
|
||||||
icon: 'pencil-alt',
|
|
||||||
index: 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'edit_community',
|
|
||||||
parentID: 'edit',
|
|
||||||
active: false,
|
|
||||||
visible: isCommunityAdmin,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.ONCLICK,
|
|
||||||
text: 'menu.section.edit_community',
|
|
||||||
function: () => {
|
|
||||||
this.modalService.open(EditCommunitySelectorComponent);
|
|
||||||
}
|
|
||||||
} as OnClickMenuItemModel,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'edit_collection',
|
|
||||||
parentID: 'edit',
|
|
||||||
active: false,
|
|
||||||
visible: isCollectionAdmin,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.ONCLICK,
|
|
||||||
text: 'menu.section.edit_collection',
|
|
||||||
function: () => {
|
|
||||||
this.modalService.open(EditCollectionSelectorComponent);
|
|
||||||
}
|
|
||||||
} as OnClickMenuItemModel,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'edit_item',
|
|
||||||
parentID: 'edit',
|
|
||||||
active: false,
|
|
||||||
visible: true,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.ONCLICK,
|
|
||||||
text: 'menu.section.edit_item',
|
|
||||||
function: () => {
|
|
||||||
this.modalService.open(EditItemSelectorComponent);
|
|
||||||
}
|
|
||||||
} as OnClickMenuItemModel,
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Statistics */
|
|
||||||
// TODO: enable this menu item once the feature has been implemented
|
|
||||||
// {
|
|
||||||
// id: 'statistics_task',
|
|
||||||
// active: false,
|
|
||||||
// visible: true,
|
|
||||||
// model: {
|
|
||||||
// type: MenuItemType.LINK,
|
|
||||||
// text: 'menu.section.statistics_task',
|
|
||||||
// link: ''
|
|
||||||
// } as LinkMenuItemModel,
|
|
||||||
// icon: 'chart-bar',
|
|
||||||
// index: 8
|
|
||||||
// },
|
|
||||||
|
|
||||||
/* Control Panel */
|
|
||||||
// TODO: enable this menu item once the feature has been implemented
|
|
||||||
// {
|
|
||||||
// id: 'control_panel',
|
|
||||||
// active: false,
|
|
||||||
// visible: isSiteAdmin,
|
|
||||||
// model: {
|
|
||||||
// type: MenuItemType.LINK,
|
|
||||||
// text: 'menu.section.control_panel',
|
|
||||||
// link: ''
|
|
||||||
// } as LinkMenuItemModel,
|
|
||||||
// icon: 'cogs',
|
|
||||||
// index: 9
|
|
||||||
// },
|
|
||||||
|
|
||||||
/* Processes */
|
|
||||||
{
|
|
||||||
id: 'processes',
|
|
||||||
active: false,
|
|
||||||
visible: isSiteAdmin,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.LINK,
|
|
||||||
text: 'menu.section.processes',
|
|
||||||
link: '/processes'
|
|
||||||
} as LinkMenuItemModel,
|
|
||||||
icon: 'terminal',
|
|
||||||
index: 10
|
|
||||||
},
|
|
||||||
];
|
|
||||||
menuList.forEach((menuSection) => this.menuService.addSection(this.menuID, Object.assign(menuSection, {
|
|
||||||
shouldPersistOnRouteChange: true
|
|
||||||
})));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create menu sections dependent on whether or not the current user is a site administrator and on whether or not
|
|
||||||
* the export scripts exist and the current user is allowed to execute them
|
|
||||||
*/
|
|
||||||
createExportMenuSections() {
|
|
||||||
const menuList = [
|
|
||||||
/* Export */
|
|
||||||
{
|
|
||||||
id: 'export',
|
|
||||||
active: false,
|
|
||||||
visible: true,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.TEXT,
|
|
||||||
text: 'menu.section.export'
|
|
||||||
} as TextMenuItemModel,
|
|
||||||
icon: 'file-export',
|
|
||||||
index: 3,
|
|
||||||
shouldPersistOnRouteChange: true
|
|
||||||
},
|
|
||||||
// TODO: enable this menu item once the feature has been implemented
|
|
||||||
// {
|
|
||||||
// id: 'export_community',
|
|
||||||
// parentID: 'export',
|
|
||||||
// active: false,
|
|
||||||
// visible: true,
|
|
||||||
// model: {
|
|
||||||
// type: MenuItemType.LINK,
|
|
||||||
// text: 'menu.section.export_community',
|
|
||||||
// link: ''
|
|
||||||
// } as LinkMenuItemModel,
|
|
||||||
// shouldPersistOnRouteChange: true
|
|
||||||
// },
|
|
||||||
// TODO: enable this menu item once the feature has been implemented
|
|
||||||
// {
|
|
||||||
// id: 'export_collection',
|
|
||||||
// parentID: 'export',
|
|
||||||
// active: false,
|
|
||||||
// visible: true,
|
|
||||||
// model: {
|
|
||||||
// type: MenuItemType.LINK,
|
|
||||||
// text: 'menu.section.export_collection',
|
|
||||||
// link: ''
|
|
||||||
// } as LinkMenuItemModel,
|
|
||||||
// shouldPersistOnRouteChange: true
|
|
||||||
// },
|
|
||||||
// TODO: enable this menu item once the feature has been implemented
|
|
||||||
// {
|
|
||||||
// id: 'export_item',
|
|
||||||
// parentID: 'export',
|
|
||||||
// active: false,
|
|
||||||
// visible: true,
|
|
||||||
// model: {
|
|
||||||
// type: MenuItemType.LINK,
|
|
||||||
// text: 'menu.section.export_item',
|
|
||||||
// link: ''
|
|
||||||
// } as LinkMenuItemModel,
|
|
||||||
// shouldPersistOnRouteChange: true
|
|
||||||
// },
|
|
||||||
];
|
|
||||||
menuList.forEach((menuSection) => this.menuService.addSection(this.menuID, menuSection));
|
|
||||||
|
|
||||||
observableCombineLatest(
|
|
||||||
this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
|
|
||||||
// this.scriptDataService.scriptWithNameExistsAndCanExecute(METADATA_EXPORT_SCRIPT_NAME)
|
|
||||||
).pipe(
|
|
||||||
// TODO uncomment when #635 (https://github.com/DSpace/dspace-angular/issues/635) is fixed; otherwise even in production mode, the metadata export button is only available after a refresh (and not in dev mode)
|
|
||||||
// filter(([authorized, metadataExportScriptExists]: boolean[]) => authorized && metadataExportScriptExists),
|
|
||||||
take(1)
|
|
||||||
).subscribe(() => {
|
|
||||||
this.menuService.addSection(this.menuID, {
|
|
||||||
id: 'export_metadata',
|
|
||||||
parentID: 'export',
|
|
||||||
active: true,
|
|
||||||
visible: true,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.ONCLICK,
|
|
||||||
text: 'menu.section.export_metadata',
|
|
||||||
function: () => {
|
|
||||||
this.modalService.open(ExportMetadataSelectorComponent);
|
|
||||||
}
|
|
||||||
} as OnClickMenuItemModel,
|
|
||||||
shouldPersistOnRouteChange: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create menu sections dependent on whether or not the current user is a site administrator and on whether or not
|
|
||||||
* the import scripts exist and the current user is allowed to execute them
|
|
||||||
*/
|
|
||||||
createImportMenuSections() {
|
|
||||||
const menuList = [
|
|
||||||
/* Import */
|
|
||||||
{
|
|
||||||
id: 'import',
|
|
||||||
active: false,
|
|
||||||
visible: true,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.TEXT,
|
|
||||||
text: 'menu.section.import'
|
|
||||||
} as TextMenuItemModel,
|
|
||||||
icon: 'file-import',
|
|
||||||
index: 2
|
|
||||||
},
|
|
||||||
// TODO: enable this menu item once the feature has been implemented
|
|
||||||
// {
|
|
||||||
// id: 'import_batch',
|
|
||||||
// parentID: 'import',
|
|
||||||
// active: false,
|
|
||||||
// visible: true,
|
|
||||||
// model: {
|
|
||||||
// type: MenuItemType.LINK,
|
|
||||||
// text: 'menu.section.import_batch',
|
|
||||||
// link: ''
|
|
||||||
// } as LinkMenuItemModel,
|
|
||||||
// }
|
|
||||||
];
|
|
||||||
menuList.forEach((menuSection) => this.menuService.addSection(this.menuID, Object.assign(menuSection, {
|
|
||||||
shouldPersistOnRouteChange: true
|
|
||||||
})));
|
|
||||||
|
|
||||||
observableCombineLatest(
|
|
||||||
this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
|
|
||||||
// this.scriptDataService.scriptWithNameExistsAndCanExecute(METADATA_IMPORT_SCRIPT_NAME)
|
|
||||||
).pipe(
|
|
||||||
// TODO uncomment when #635 (https://github.com/DSpace/dspace-angular/issues/635) is fixed
|
|
||||||
// filter(([authorized, metadataImportScriptExists]: boolean[]) => authorized && metadataImportScriptExists),
|
|
||||||
take(1)
|
|
||||||
).subscribe(() => {
|
|
||||||
this.menuService.addSection(this.menuID, {
|
|
||||||
id: 'import_metadata',
|
|
||||||
parentID: 'import',
|
|
||||||
active: true,
|
|
||||||
visible: true,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.LINK,
|
|
||||||
text: 'menu.section.import_metadata',
|
|
||||||
link: '/admin/metadata-import'
|
|
||||||
} as LinkMenuItemModel,
|
|
||||||
shouldPersistOnRouteChange: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create menu sections dependent on whether or not the current user is a site administrator
|
|
||||||
*/
|
|
||||||
createSiteAdministratorMenuSections() {
|
|
||||||
this.authorizationService.isAuthorized(FeatureID.AdministratorOf).subscribe((authorized) => {
|
|
||||||
const menuList = [
|
|
||||||
/* Admin Search */
|
|
||||||
{
|
|
||||||
id: 'admin_search',
|
|
||||||
active: false,
|
|
||||||
visible: authorized,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.LINK,
|
|
||||||
text: 'menu.section.admin_search',
|
|
||||||
link: '/admin/search'
|
|
||||||
} as LinkMenuItemModel,
|
|
||||||
icon: 'search',
|
|
||||||
index: 5
|
|
||||||
},
|
|
||||||
/* Registries */
|
|
||||||
{
|
|
||||||
id: 'registries',
|
|
||||||
active: false,
|
|
||||||
visible: authorized,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.TEXT,
|
|
||||||
text: 'menu.section.registries'
|
|
||||||
} as TextMenuItemModel,
|
|
||||||
icon: 'list',
|
|
||||||
index: 6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'registries_metadata',
|
|
||||||
parentID: 'registries',
|
|
||||||
active: false,
|
|
||||||
visible: authorized,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.LINK,
|
|
||||||
text: 'menu.section.registries_metadata',
|
|
||||||
link: 'admin/registries/metadata'
|
|
||||||
} as LinkMenuItemModel,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'registries_format',
|
|
||||||
parentID: 'registries',
|
|
||||||
active: false,
|
|
||||||
visible: authorized,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.LINK,
|
|
||||||
text: 'menu.section.registries_format',
|
|
||||||
link: 'admin/registries/bitstream-formats'
|
|
||||||
} as LinkMenuItemModel,
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Curation tasks */
|
|
||||||
{
|
|
||||||
id: 'curation_tasks',
|
|
||||||
active: false,
|
|
||||||
visible: authorized,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.LINK,
|
|
||||||
text: 'menu.section.curation_task',
|
|
||||||
link: 'admin/curation-tasks'
|
|
||||||
} as LinkMenuItemModel,
|
|
||||||
icon: 'filter',
|
|
||||||
index: 7
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Workflow */
|
|
||||||
{
|
|
||||||
id: 'workflow',
|
|
||||||
active: false,
|
|
||||||
visible: authorized,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.LINK,
|
|
||||||
text: 'menu.section.workflow',
|
|
||||||
link: '/admin/workflow'
|
|
||||||
} as LinkMenuItemModel,
|
|
||||||
icon: 'user-check',
|
|
||||||
index: 11
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
menuList.forEach((menuSection) => this.menuService.addSection(this.menuID, Object.assign(menuSection, {
|
|
||||||
shouldPersistOnRouteChange: true
|
|
||||||
})));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create menu sections dependent on whether or not the current user can manage access control groups
|
|
||||||
*/
|
|
||||||
createAccessControlMenuSections() {
|
|
||||||
observableCombineLatest(
|
|
||||||
this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
|
|
||||||
this.authorizationService.isAuthorized(FeatureID.CanManageGroups)
|
|
||||||
).subscribe(([isSiteAdmin, canManageGroups]) => {
|
|
||||||
const menuList = [
|
|
||||||
/* Access Control */
|
|
||||||
{
|
|
||||||
id: 'access_control_people',
|
|
||||||
parentID: 'access_control',
|
|
||||||
active: false,
|
|
||||||
visible: isSiteAdmin,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.LINK,
|
|
||||||
text: 'menu.section.access_control_people',
|
|
||||||
link: '/access-control/epeople'
|
|
||||||
} as LinkMenuItemModel,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'access_control_groups',
|
|
||||||
parentID: 'access_control',
|
|
||||||
active: false,
|
|
||||||
visible: canManageGroups,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.LINK,
|
|
||||||
text: 'menu.section.access_control_groups',
|
|
||||||
link: '/access-control/groups'
|
|
||||||
} as LinkMenuItemModel,
|
|
||||||
},
|
|
||||||
// TODO: enable this menu item once the feature has been implemented
|
|
||||||
// {
|
|
||||||
// id: 'access_control_authorizations',
|
|
||||||
// parentID: 'access_control',
|
|
||||||
// active: false,
|
|
||||||
// visible: authorized,
|
|
||||||
// model: {
|
|
||||||
// type: MenuItemType.LINK,
|
|
||||||
// text: 'menu.section.access_control_authorizations',
|
|
||||||
// link: ''
|
|
||||||
// } as LinkMenuItemModel,
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
id: 'access_control',
|
|
||||||
active: false,
|
|
||||||
visible: canManageGroups || isSiteAdmin,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.TEXT,
|
|
||||||
text: 'menu.section.access_control'
|
|
||||||
} as TextMenuItemModel,
|
|
||||||
icon: 'key',
|
|
||||||
index: 4
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
menuList.forEach((menuSection) => this.menuService.addSection(this.menuID, Object.assign(menuSection, {
|
|
||||||
shouldPersistOnRouteChange: true,
|
|
||||||
})));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@HostListener('focusin')
|
@HostListener('focusin')
|
||||||
public handleFocusIn() {
|
public handleFocusIn() {
|
||||||
this.inFocus$.next(true);
|
this.inFocus$.next(true);
|
||||||
|
@@ -1,16 +1,305 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||||
|
|
||||||
import { MenuResolver } from './menu.resolver';
|
import { MenuResolver } from './menu.resolver';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
import { FeatureID } from './core/data/feature-authorization/feature-id';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
|
import { AdminSidebarComponent } from './admin/admin-sidebar/admin-sidebar.component';
|
||||||
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { MenuService } from './shared/menu/menu.service';
|
||||||
|
import { AuthorizationDataService } from './core/data/feature-authorization/authorization-data.service';
|
||||||
|
import { ScriptDataService } from './core/data/processes/script-data.service';
|
||||||
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { MenuServiceStub } from './shared/testing/menu-service.stub';
|
||||||
|
import { MenuID } from './shared/menu/initial-menus-state';
|
||||||
|
import { BrowseService } from './core/browse/browse.service';
|
||||||
|
import { cold } from 'jasmine-marbles';
|
||||||
|
import createSpy = jasmine.createSpy;
|
||||||
|
import { createSuccessfulRemoteDataObject$ } from './shared/remote-data.utils';
|
||||||
|
import { createPaginatedList } from './shared/testing/utils.test';
|
||||||
|
|
||||||
|
const BOOLEAN = { t: true, f: false };
|
||||||
|
const MENU_STATE = {
|
||||||
|
id: 'some menu'
|
||||||
|
};
|
||||||
|
const BROWSE_DEFINITIONS = [
|
||||||
|
{ id: 'definition1' },
|
||||||
|
{ id: 'definition2' },
|
||||||
|
{ id: 'definition3' },
|
||||||
|
];
|
||||||
|
|
||||||
describe('MenuResolver', () => {
|
describe('MenuResolver', () => {
|
||||||
let resolver: MenuResolver;
|
let resolver: MenuResolver;
|
||||||
|
|
||||||
beforeEach(() => {
|
let menuService;
|
||||||
TestBed.configureTestingModule({});
|
let browseService;
|
||||||
|
let authorizationService;
|
||||||
|
let scriptService;
|
||||||
|
|
||||||
|
beforeEach(waitForAsync(() => {
|
||||||
|
menuService = new MenuServiceStub();
|
||||||
|
spyOn(menuService, 'getMenu').and.returnValue(observableOf(MENU_STATE));
|
||||||
|
|
||||||
|
browseService = jasmine.createSpyObj('browseService', {
|
||||||
|
getBrowseDefinitions: createSuccessfulRemoteDataObject$(createPaginatedList(BROWSE_DEFINITIONS))
|
||||||
|
});
|
||||||
|
authorizationService = jasmine.createSpyObj('authorizationService', {
|
||||||
|
isAuthorized: observableOf(true)
|
||||||
|
});
|
||||||
|
scriptService = jasmine.createSpyObj('scriptService', {
|
||||||
|
scriptWithNameExistsAndCanExecute: observableOf(true)
|
||||||
|
});
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [TranslateModule.forRoot(), NoopAnimationsModule, RouterTestingModule],
|
||||||
|
declarations: [AdminSidebarComponent],
|
||||||
|
providers: [
|
||||||
|
{ provide: MenuService, useValue: menuService },
|
||||||
|
{ provide: BrowseService, useValue: browseService },
|
||||||
|
{ provide: AuthorizationDataService, useValue: authorizationService },
|
||||||
|
{ provide: ScriptDataService, useValue: scriptService },
|
||||||
|
{
|
||||||
|
provide: NgbModal, useValue: {
|
||||||
|
open: () => {/*comment*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
});
|
||||||
resolver = TestBed.inject(MenuResolver);
|
resolver = TestBed.inject(MenuResolver);
|
||||||
});
|
|
||||||
|
spyOn(menuService, 'addSection');
|
||||||
|
}));
|
||||||
|
|
||||||
it('should be created', () => {
|
it('should be created', () => {
|
||||||
expect(resolver).toBeTruthy();
|
expect(resolver).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('resolve', () => {
|
||||||
|
it('should create all menus', (done) => {
|
||||||
|
spyOn(resolver, 'createPublicMenu$').and.returnValue(observableOf(true));
|
||||||
|
spyOn(resolver, 'createAdminMenu$').and.returnValue(observableOf(true));
|
||||||
|
|
||||||
|
resolver.resolve(null, null).subscribe(resolved => {
|
||||||
|
expect(resolved).toBeTrue();
|
||||||
|
expect(resolver.createPublicMenu$).toHaveBeenCalled();
|
||||||
|
expect(resolver.createAdminMenu$).toHaveBeenCalled();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an Observable that emits true as soon as all menus are created', () => {
|
||||||
|
spyOn(resolver, 'createPublicMenu$').and.returnValue(cold('--(t|)', BOOLEAN));
|
||||||
|
spyOn(resolver, 'createAdminMenu$').and.returnValue(cold('----(t|)', BOOLEAN));
|
||||||
|
|
||||||
|
expect(resolver.resolve(null, null)).toBeObservable(cold('----(t|)', BOOLEAN));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('createPublicMenu$', () => {
|
||||||
|
it('should retrieve the menu by ID return an Observable that emits true as soon as it is created', () => {
|
||||||
|
(menuService as any).getMenu.and.returnValue(cold('--u--m--', {
|
||||||
|
u: undefined,
|
||||||
|
m: MENU_STATE,
|
||||||
|
}));
|
||||||
|
|
||||||
|
expect(resolver.createPublicMenu$()).toBeObservable(cold('-----(t|)', BOOLEAN));
|
||||||
|
expect(menuService.getMenu).toHaveBeenCalledOnceWith(MenuID.PUBLIC);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('contents', () => {
|
||||||
|
beforeEach((done) => {
|
||||||
|
resolver.createPublicMenu$().subscribe((_) => {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include community list link', () => {
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.PUBLIC, jasmine.objectContaining({
|
||||||
|
id: 'browse_global_communities_and_collections', visible: true,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include browse dropdown', () => {
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.PUBLIC, jasmine.objectContaining({
|
||||||
|
id: 'browse_global_by_definition1', parentID: 'browse_global', visible: true,
|
||||||
|
}));
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.PUBLIC, jasmine.objectContaining({
|
||||||
|
id: 'browse_global_by_definition2', parentID: 'browse_global', visible: true,
|
||||||
|
}));
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.PUBLIC, jasmine.objectContaining({
|
||||||
|
id: 'browse_global_by_definition3', parentID: 'browse_global', visible: true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.PUBLIC, jasmine.objectContaining({
|
||||||
|
id: 'browse_global', visible: true,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('createAdminMenu$', () => {
|
||||||
|
it('should retrieve the menu by ID return an Observable that emits true as soon as it is created', () => {
|
||||||
|
(menuService as any).getMenu.and.returnValue(cold('--u--m', {
|
||||||
|
u: undefined,
|
||||||
|
m: MENU_STATE,
|
||||||
|
}));
|
||||||
|
|
||||||
|
expect(resolver.createAdminMenu$()).toBeObservable(cold('-----(t|)', BOOLEAN));
|
||||||
|
expect(menuService.getMenu).toHaveBeenCalledOnceWith(MenuID.ADMIN);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('for regular user', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake(() => {
|
||||||
|
return observableOf(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach((done) => {
|
||||||
|
resolver.createAdminMenu$().subscribe((_) => {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not show site admin section', () => {
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'admin_search', visible: false,
|
||||||
|
}));
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'registries', visible: false,
|
||||||
|
}));
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
parentID: 'registries', visible: false,
|
||||||
|
}));
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'curation_tasks', visible: false,
|
||||||
|
}));
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'workflow', visible: false,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not show edit_community', () => {
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'edit_community', visible: false,
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not show edit_collection', () => {
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'edit_collection', visible: false,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not show access control section', () => {
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'access_control', visible: false,
|
||||||
|
}));
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
parentID: 'access_control', visible: false,
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('for site admin', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake((featureID: FeatureID) => {
|
||||||
|
return observableOf(featureID === FeatureID.AdministratorOf);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach((done) => {
|
||||||
|
resolver.createAdminMenu$().subscribe((_) => {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should contain site admin section', () => {
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'admin_search', visible: true,
|
||||||
|
}));
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'registries', visible: true,
|
||||||
|
}));
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
parentID: 'registries', visible: true,
|
||||||
|
}));
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'curation_tasks', visible: true,
|
||||||
|
}));
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'workflow', visible: true,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('for community admin', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake((featureID: FeatureID) => {
|
||||||
|
return observableOf(featureID === FeatureID.IsCommunityAdmin);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach((done) => {
|
||||||
|
resolver.createAdminMenu$().subscribe((_) => {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show edit_community', () => {
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'edit_community', visible: true,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('for collection admin', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake((featureID: FeatureID) => {
|
||||||
|
return observableOf(featureID === FeatureID.IsCollectionAdmin);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach((done) => {
|
||||||
|
resolver.createAdminMenu$().subscribe((_) => {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show edit_collection', () => {
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'edit_collection', visible: true,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('for group admin', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake((featureID: FeatureID) => {
|
||||||
|
return observableOf(featureID === FeatureID.CanManageGroups);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach((done) => {
|
||||||
|
resolver.createAdminMenu$().subscribe((_) => {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show access control section', () => {
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
id: 'access_control', visible: true,
|
||||||
|
}));
|
||||||
|
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
|
||||||
|
parentID: 'access_control', visible: true,
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Resolve, RouterStateSnapshot, ActivatedRouteSnapshot } from '@angular/router';
|
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||||
import { Observable } from 'rxjs';
|
import { combineLatest as observableCombineLatest, combineLatest, Observable } from 'rxjs';
|
||||||
import { MenuItemType, MenuID } from './shared/menu/initial-menus-state';
|
import { MenuID, MenuItemType } from './shared/menu/initial-menus-state';
|
||||||
import { LinkMenuItemModel } from './shared/menu/menu-item/models/link.model';
|
import { LinkMenuItemModel } from './shared/menu/menu-item/models/link.model';
|
||||||
import { getFirstCompletedRemoteData } from './core/shared/operators';
|
import { getFirstCompletedRemoteData } from './core/shared/operators';
|
||||||
import { PaginatedList } from './core/data/paginated-list.model';
|
import { PaginatedList } from './core/data/paginated-list.model';
|
||||||
@@ -11,28 +11,63 @@ import { TextMenuItemModel } from './shared/menu/menu-item/models/text.model';
|
|||||||
import { BrowseService } from './core/browse/browse.service';
|
import { BrowseService } from './core/browse/browse.service';
|
||||||
import { MenuService } from './shared/menu/menu.service';
|
import { MenuService } from './shared/menu/menu.service';
|
||||||
import { MenuState } from './shared/menu/menu.reducer';
|
import { MenuState } from './shared/menu/menu.reducer';
|
||||||
import { find, map } from 'rxjs/operators';
|
import { find, map, take } from 'rxjs/operators';
|
||||||
import { hasValue } from './shared/empty.util';
|
import { hasValue } from './shared/empty.util';
|
||||||
|
import { FeatureID } from './core/data/feature-authorization/feature-id';
|
||||||
|
import { CreateCommunityParentSelectorComponent } from './shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component';
|
||||||
|
import { OnClickMenuItemModel } from './shared/menu/menu-item/models/onclick.model';
|
||||||
|
import { CreateCollectionParentSelectorComponent } from './shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component';
|
||||||
|
import { CreateItemParentSelectorComponent } from './shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component';
|
||||||
|
import { EditCommunitySelectorComponent } from './shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component';
|
||||||
|
import { EditCollectionSelectorComponent } from './shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component';
|
||||||
|
import { EditItemSelectorComponent } from './shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component';
|
||||||
|
import { ExportMetadataSelectorComponent } from './shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component';
|
||||||
|
import { AuthorizationDataService } from './core/data/feature-authorization/authorization-data.service';
|
||||||
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates all of the app's menus
|
||||||
|
*/
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
export class MenuResolver implements Resolve<boolean> {
|
export class MenuResolver implements Resolve<boolean> {
|
||||||
constructor(
|
constructor(
|
||||||
protected menuService: MenuService,
|
protected menuService: MenuService,
|
||||||
public browseService: BrowseService,
|
protected browseService: BrowseService,
|
||||||
|
protected authorizationService: AuthorizationDataService,
|
||||||
|
protected modalService: NgbModal,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all menus
|
||||||
|
*/
|
||||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
|
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
|
||||||
this.createPublicMenu();
|
return combineLatest([
|
||||||
return this.menuService.getMenu(MenuID.PUBLIC).pipe(
|
this.createPublicMenu$(),
|
||||||
find((menu: MenuState) => hasValue(menu)),
|
this.createAdminMenu$(),
|
||||||
map(() => true)
|
]).pipe(
|
||||||
|
map((menusDone: boolean[]) => menusDone.every(Boolean)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
createPublicMenu() {
|
/**
|
||||||
|
* Wait for a specific menu to appear
|
||||||
|
* @param id the ID of the menu to wait for
|
||||||
|
* @return an Observable that emits true as soon as the menu is created
|
||||||
|
*/
|
||||||
|
protected waitForMenu$(id: MenuID): Observable<boolean> {
|
||||||
|
return this.menuService.getMenu(id).pipe(
|
||||||
|
find((menu: MenuState) => hasValue(menu)),
|
||||||
|
map(() => true),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all menu sections and items for {@link MenuID.PUBLIC}
|
||||||
|
*/
|
||||||
|
createPublicMenu$(): Observable<boolean> {
|
||||||
const menuList: any[] = [
|
const menuList: any[] = [
|
||||||
/* Communities & Collections tree */
|
/* Communities & Collections tree */
|
||||||
{
|
{
|
||||||
@@ -84,6 +119,504 @@ export class MenuResolver implements Resolve<boolean> {
|
|||||||
})));
|
})));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return this.waitForMenu$(MenuID.PUBLIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all menu sections and items for {@link MenuID.ADMIN}
|
||||||
|
*/
|
||||||
|
createAdminMenu$() {
|
||||||
|
this.createMainMenuSections();
|
||||||
|
this.createSiteAdministratorMenuSections();
|
||||||
|
this.createExportMenuSections();
|
||||||
|
this.createImportMenuSections();
|
||||||
|
this.createAccessControlMenuSections();
|
||||||
|
|
||||||
|
return this.waitForMenu$(MenuID.ADMIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the main menu sections.
|
||||||
|
* edit_community / edit_collection is only included if the current user is a Community or Collection admin
|
||||||
|
*/
|
||||||
|
createMainMenuSections() {
|
||||||
|
combineLatest([
|
||||||
|
this.authorizationService.isAuthorized(FeatureID.IsCollectionAdmin),
|
||||||
|
this.authorizationService.isAuthorized(FeatureID.IsCommunityAdmin),
|
||||||
|
this.authorizationService.isAuthorized(FeatureID.AdministratorOf)
|
||||||
|
]).subscribe(([isCollectionAdmin, isCommunityAdmin, isSiteAdmin]) => {
|
||||||
|
const menuList = [
|
||||||
|
/* News */
|
||||||
|
{
|
||||||
|
id: 'new',
|
||||||
|
active: false,
|
||||||
|
visible: true,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.TEXT,
|
||||||
|
text: 'menu.section.new'
|
||||||
|
} as TextMenuItemModel,
|
||||||
|
icon: 'plus',
|
||||||
|
index: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'new_community',
|
||||||
|
parentID: 'new',
|
||||||
|
active: false,
|
||||||
|
visible: isCommunityAdmin,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.ONCLICK,
|
||||||
|
text: 'menu.section.new_community',
|
||||||
|
function: () => {
|
||||||
|
this.modalService.open(CreateCommunityParentSelectorComponent);
|
||||||
|
}
|
||||||
|
} as OnClickMenuItemModel,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'new_collection',
|
||||||
|
parentID: 'new',
|
||||||
|
active: false,
|
||||||
|
visible: isCommunityAdmin,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.ONCLICK,
|
||||||
|
text: 'menu.section.new_collection',
|
||||||
|
function: () => {
|
||||||
|
this.modalService.open(CreateCollectionParentSelectorComponent);
|
||||||
|
}
|
||||||
|
} as OnClickMenuItemModel,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'new_item',
|
||||||
|
parentID: 'new',
|
||||||
|
active: false,
|
||||||
|
visible: true,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.ONCLICK,
|
||||||
|
text: 'menu.section.new_item',
|
||||||
|
function: () => {
|
||||||
|
this.modalService.open(CreateItemParentSelectorComponent);
|
||||||
|
}
|
||||||
|
} as OnClickMenuItemModel,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'new_process',
|
||||||
|
parentID: 'new',
|
||||||
|
active: false,
|
||||||
|
visible: isCollectionAdmin,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: 'menu.section.new_process',
|
||||||
|
link: '/processes/new'
|
||||||
|
} as LinkMenuItemModel,
|
||||||
|
},
|
||||||
|
// 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,
|
||||||
|
// },
|
||||||
|
|
||||||
|
/* Edit */
|
||||||
|
{
|
||||||
|
id: 'edit',
|
||||||
|
active: false,
|
||||||
|
visible: true,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.TEXT,
|
||||||
|
text: 'menu.section.edit'
|
||||||
|
} as TextMenuItemModel,
|
||||||
|
icon: 'pencil-alt',
|
||||||
|
index: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'edit_community',
|
||||||
|
parentID: 'edit',
|
||||||
|
active: false,
|
||||||
|
visible: isCommunityAdmin,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.ONCLICK,
|
||||||
|
text: 'menu.section.edit_community',
|
||||||
|
function: () => {
|
||||||
|
this.modalService.open(EditCommunitySelectorComponent);
|
||||||
|
}
|
||||||
|
} as OnClickMenuItemModel,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'edit_collection',
|
||||||
|
parentID: 'edit',
|
||||||
|
active: false,
|
||||||
|
visible: isCollectionAdmin,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.ONCLICK,
|
||||||
|
text: 'menu.section.edit_collection',
|
||||||
|
function: () => {
|
||||||
|
this.modalService.open(EditCollectionSelectorComponent);
|
||||||
|
}
|
||||||
|
} as OnClickMenuItemModel,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'edit_item',
|
||||||
|
parentID: 'edit',
|
||||||
|
active: false,
|
||||||
|
visible: true,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.ONCLICK,
|
||||||
|
text: 'menu.section.edit_item',
|
||||||
|
function: () => {
|
||||||
|
this.modalService.open(EditItemSelectorComponent);
|
||||||
|
}
|
||||||
|
} as OnClickMenuItemModel,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Statistics */
|
||||||
|
// TODO: enable this menu item once the feature has been implemented
|
||||||
|
// {
|
||||||
|
// id: 'statistics_task',
|
||||||
|
// active: false,
|
||||||
|
// visible: true,
|
||||||
|
// model: {
|
||||||
|
// type: MenuItemType.LINK,
|
||||||
|
// text: 'menu.section.statistics_task',
|
||||||
|
// link: ''
|
||||||
|
// } as LinkMenuItemModel,
|
||||||
|
// icon: 'chart-bar',
|
||||||
|
// index: 8
|
||||||
|
// },
|
||||||
|
|
||||||
|
/* Control Panel */
|
||||||
|
// TODO: enable this menu item once the feature has been implemented
|
||||||
|
// {
|
||||||
|
// id: 'control_panel',
|
||||||
|
// active: false,
|
||||||
|
// visible: isSiteAdmin,
|
||||||
|
// model: {
|
||||||
|
// type: MenuItemType.LINK,
|
||||||
|
// text: 'menu.section.control_panel',
|
||||||
|
// link: ''
|
||||||
|
// } as LinkMenuItemModel,
|
||||||
|
// icon: 'cogs',
|
||||||
|
// index: 9
|
||||||
|
// },
|
||||||
|
|
||||||
|
/* Processes */
|
||||||
|
{
|
||||||
|
id: 'processes',
|
||||||
|
active: false,
|
||||||
|
visible: isSiteAdmin,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: 'menu.section.processes',
|
||||||
|
link: '/processes'
|
||||||
|
} as LinkMenuItemModel,
|
||||||
|
icon: 'terminal',
|
||||||
|
index: 10
|
||||||
|
},
|
||||||
|
];
|
||||||
|
menuList.forEach((menuSection) => this.menuService.addSection(MenuID.ADMIN, Object.assign(menuSection, {
|
||||||
|
shouldPersistOnRouteChange: true
|
||||||
|
})));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create menu sections dependent on whether or not the current user is a site administrator and on whether or not
|
||||||
|
* the export scripts exist and the current user is allowed to execute them
|
||||||
|
*/
|
||||||
|
createExportMenuSections() {
|
||||||
|
const menuList = [
|
||||||
|
/* Export */
|
||||||
|
{
|
||||||
|
id: 'export',
|
||||||
|
active: false,
|
||||||
|
visible: true,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.TEXT,
|
||||||
|
text: 'menu.section.export'
|
||||||
|
} as TextMenuItemModel,
|
||||||
|
icon: 'file-export',
|
||||||
|
index: 3,
|
||||||
|
shouldPersistOnRouteChange: true
|
||||||
|
},
|
||||||
|
// TODO: enable this menu item once the feature has been implemented
|
||||||
|
// {
|
||||||
|
// id: 'export_community',
|
||||||
|
// parentID: 'export',
|
||||||
|
// active: false,
|
||||||
|
// visible: true,
|
||||||
|
// model: {
|
||||||
|
// type: MenuItemType.LINK,
|
||||||
|
// text: 'menu.section.export_community',
|
||||||
|
// link: ''
|
||||||
|
// } as LinkMenuItemModel,
|
||||||
|
// shouldPersistOnRouteChange: true
|
||||||
|
// },
|
||||||
|
// TODO: enable this menu item once the feature has been implemented
|
||||||
|
// {
|
||||||
|
// id: 'export_collection',
|
||||||
|
// parentID: 'export',
|
||||||
|
// active: false,
|
||||||
|
// visible: true,
|
||||||
|
// model: {
|
||||||
|
// type: MenuItemType.LINK,
|
||||||
|
// text: 'menu.section.export_collection',
|
||||||
|
// link: ''
|
||||||
|
// } as LinkMenuItemModel,
|
||||||
|
// shouldPersistOnRouteChange: true
|
||||||
|
// },
|
||||||
|
// TODO: enable this menu item once the feature has been implemented
|
||||||
|
// {
|
||||||
|
// id: 'export_item',
|
||||||
|
// parentID: 'export',
|
||||||
|
// active: false,
|
||||||
|
// visible: true,
|
||||||
|
// model: {
|
||||||
|
// type: MenuItemType.LINK,
|
||||||
|
// text: 'menu.section.export_item',
|
||||||
|
// link: ''
|
||||||
|
// } as LinkMenuItemModel,
|
||||||
|
// shouldPersistOnRouteChange: true
|
||||||
|
// },
|
||||||
|
];
|
||||||
|
menuList.forEach((menuSection) => this.menuService.addSection(MenuID.ADMIN, menuSection));
|
||||||
|
|
||||||
|
observableCombineLatest(
|
||||||
|
this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
|
||||||
|
// this.scriptDataService.scriptWithNameExistsAndCanExecute(METADATA_EXPORT_SCRIPT_NAME)
|
||||||
|
).pipe(
|
||||||
|
// TODO uncomment when #635 (https://github.com/DSpace/dspace-angular/issues/635) is fixed; otherwise even in production mode, the metadata export button is only available after a refresh (and not in dev mode)
|
||||||
|
// filter(([authorized, metadataExportScriptExists]: boolean[]) => authorized && metadataExportScriptExists),
|
||||||
|
take(1)
|
||||||
|
).subscribe(() => {
|
||||||
|
this.menuService.addSection(MenuID.ADMIN, {
|
||||||
|
id: 'export_metadata',
|
||||||
|
parentID: 'export',
|
||||||
|
active: true,
|
||||||
|
visible: true,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.ONCLICK,
|
||||||
|
text: 'menu.section.export_metadata',
|
||||||
|
function: () => {
|
||||||
|
this.modalService.open(ExportMetadataSelectorComponent);
|
||||||
|
}
|
||||||
|
} as OnClickMenuItemModel,
|
||||||
|
shouldPersistOnRouteChange: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create menu sections dependent on whether or not the current user is a site administrator and on whether or not
|
||||||
|
* the import scripts exist and the current user is allowed to execute them
|
||||||
|
*/
|
||||||
|
createImportMenuSections() {
|
||||||
|
const menuList = [
|
||||||
|
/* Import */
|
||||||
|
{
|
||||||
|
id: 'import',
|
||||||
|
active: false,
|
||||||
|
visible: true,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.TEXT,
|
||||||
|
text: 'menu.section.import'
|
||||||
|
} as TextMenuItemModel,
|
||||||
|
icon: 'file-import',
|
||||||
|
index: 2
|
||||||
|
},
|
||||||
|
// TODO: enable this menu item once the feature has been implemented
|
||||||
|
// {
|
||||||
|
// id: 'import_batch',
|
||||||
|
// parentID: 'import',
|
||||||
|
// active: false,
|
||||||
|
// visible: true,
|
||||||
|
// model: {
|
||||||
|
// type: MenuItemType.LINK,
|
||||||
|
// text: 'menu.section.import_batch',
|
||||||
|
// link: ''
|
||||||
|
// } as LinkMenuItemModel,
|
||||||
|
// }
|
||||||
|
];
|
||||||
|
menuList.forEach((menuSection) => this.menuService.addSection(MenuID.ADMIN, Object.assign(menuSection, {
|
||||||
|
shouldPersistOnRouteChange: true
|
||||||
|
})));
|
||||||
|
|
||||||
|
observableCombineLatest(
|
||||||
|
this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
|
||||||
|
// this.scriptDataService.scriptWithNameExistsAndCanExecute(METADATA_IMPORT_SCRIPT_NAME)
|
||||||
|
).pipe(
|
||||||
|
// TODO uncomment when #635 (https://github.com/DSpace/dspace-angular/issues/635) is fixed
|
||||||
|
// filter(([authorized, metadataImportScriptExists]: boolean[]) => authorized && metadataImportScriptExists),
|
||||||
|
take(1)
|
||||||
|
).subscribe(() => {
|
||||||
|
this.menuService.addSection(MenuID.ADMIN, {
|
||||||
|
id: 'import_metadata',
|
||||||
|
parentID: 'import',
|
||||||
|
active: true,
|
||||||
|
visible: true,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: 'menu.section.import_metadata',
|
||||||
|
link: '/admin/metadata-import'
|
||||||
|
} as LinkMenuItemModel,
|
||||||
|
shouldPersistOnRouteChange: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create menu sections dependent on whether or not the current user is a site administrator
|
||||||
|
*/
|
||||||
|
createSiteAdministratorMenuSections() {
|
||||||
|
this.authorizationService.isAuthorized(FeatureID.AdministratorOf).subscribe((authorized) => {
|
||||||
|
const menuList = [
|
||||||
|
/* Admin Search */
|
||||||
|
{
|
||||||
|
id: 'admin_search',
|
||||||
|
active: false,
|
||||||
|
visible: authorized,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: 'menu.section.admin_search',
|
||||||
|
link: '/admin/search'
|
||||||
|
} as LinkMenuItemModel,
|
||||||
|
icon: 'search',
|
||||||
|
index: 5
|
||||||
|
},
|
||||||
|
/* Registries */
|
||||||
|
{
|
||||||
|
id: 'registries',
|
||||||
|
active: false,
|
||||||
|
visible: authorized,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.TEXT,
|
||||||
|
text: 'menu.section.registries'
|
||||||
|
} as TextMenuItemModel,
|
||||||
|
icon: 'list',
|
||||||
|
index: 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'registries_metadata',
|
||||||
|
parentID: 'registries',
|
||||||
|
active: false,
|
||||||
|
visible: authorized,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: 'menu.section.registries_metadata',
|
||||||
|
link: 'admin/registries/metadata'
|
||||||
|
} as LinkMenuItemModel,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'registries_format',
|
||||||
|
parentID: 'registries',
|
||||||
|
active: false,
|
||||||
|
visible: authorized,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: 'menu.section.registries_format',
|
||||||
|
link: 'admin/registries/bitstream-formats'
|
||||||
|
} as LinkMenuItemModel,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Curation tasks */
|
||||||
|
{
|
||||||
|
id: 'curation_tasks',
|
||||||
|
active: false,
|
||||||
|
visible: authorized,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: 'menu.section.curation_task',
|
||||||
|
link: 'admin/curation-tasks'
|
||||||
|
} as LinkMenuItemModel,
|
||||||
|
icon: 'filter',
|
||||||
|
index: 7
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Workflow */
|
||||||
|
{
|
||||||
|
id: 'workflow',
|
||||||
|
active: false,
|
||||||
|
visible: authorized,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: 'menu.section.workflow',
|
||||||
|
link: '/admin/workflow'
|
||||||
|
} as LinkMenuItemModel,
|
||||||
|
icon: 'user-check',
|
||||||
|
index: 11
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
menuList.forEach((menuSection) => this.menuService.addSection(MenuID.ADMIN, Object.assign(menuSection, {
|
||||||
|
shouldPersistOnRouteChange: true
|
||||||
|
})));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create menu sections dependent on whether or not the current user can manage access control groups
|
||||||
|
*/
|
||||||
|
createAccessControlMenuSections() {
|
||||||
|
observableCombineLatest(
|
||||||
|
this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
|
||||||
|
this.authorizationService.isAuthorized(FeatureID.CanManageGroups)
|
||||||
|
).subscribe(([isSiteAdmin, canManageGroups]) => {
|
||||||
|
const menuList = [
|
||||||
|
/* Access Control */
|
||||||
|
{
|
||||||
|
id: 'access_control_people',
|
||||||
|
parentID: 'access_control',
|
||||||
|
active: false,
|
||||||
|
visible: isSiteAdmin,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: 'menu.section.access_control_people',
|
||||||
|
link: '/access-control/epeople'
|
||||||
|
} as LinkMenuItemModel,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'access_control_groups',
|
||||||
|
parentID: 'access_control',
|
||||||
|
active: false,
|
||||||
|
visible: canManageGroups,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: 'menu.section.access_control_groups',
|
||||||
|
link: '/access-control/groups'
|
||||||
|
} as LinkMenuItemModel,
|
||||||
|
},
|
||||||
|
// TODO: enable this menu item once the feature has been implemented
|
||||||
|
// {
|
||||||
|
// id: 'access_control_authorizations',
|
||||||
|
// parentID: 'access_control',
|
||||||
|
// active: false,
|
||||||
|
// visible: authorized,
|
||||||
|
// model: {
|
||||||
|
// type: MenuItemType.LINK,
|
||||||
|
// text: 'menu.section.access_control_authorizations',
|
||||||
|
// link: ''
|
||||||
|
// } as LinkMenuItemModel,
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
id: 'access_control',
|
||||||
|
active: false,
|
||||||
|
visible: canManageGroups || isSiteAdmin,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.TEXT,
|
||||||
|
text: 'menu.section.access_control'
|
||||||
|
} as TextMenuItemModel,
|
||||||
|
icon: 'key',
|
||||||
|
index: 4
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
menuList.forEach((menuSection) => this.menuService.addSection(MenuID.ADMIN, Object.assign(menuSection, {
|
||||||
|
shouldPersistOnRouteChange: true,
|
||||||
|
})));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { MenuID } from '../menu/initial-menus-state';
|
import { MenuID } from '../menu/initial-menus-state';
|
||||||
import { Observable, of as observableOf } from 'rxjs';
|
import { Observable, of as observableOf } from 'rxjs';
|
||||||
import { MenuSection } from '../menu/menu.reducer';
|
import { MenuSection, MenuState } from '../menu/menu.reducer';
|
||||||
|
|
||||||
export class MenuServiceStub {
|
export class MenuServiceStub {
|
||||||
visibleSection1 = {
|
visibleSection1 = {
|
||||||
@@ -77,6 +77,10 @@ export class MenuServiceStub {
|
|||||||
return observableOf(true);
|
return observableOf(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMenu(id: MenuID): Observable<MenuState> {
|
||||||
|
return observableOf({} as MenuState);
|
||||||
|
}
|
||||||
|
|
||||||
getMenuTopSections(id: MenuID): Observable<MenuSection[]> {
|
getMenuTopSections(id: MenuID): Observable<MenuSection[]> {
|
||||||
return observableOf([this.visibleSection1, this.visibleSection2]);
|
return observableOf([this.visibleSection1, this.visibleSection2]);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user