From 1f768071693d761b7354e1c7c432fb60ec0598e2 Mon Sep 17 00:00:00 2001 From: Sofia Papacharalampous Date: Tue, 2 Jul 2024 18:05:26 +0300 Subject: [PATCH] made sidebar's info-items configurable --- .../configuration-models/sidebar.model.ts | 78 ++++++++++++++++++ .../configuration/configuration.service.ts | 7 ++ .../src/app/ui/sidebar/sidebar.component.html | 65 ++++++++------- .../src/app/ui/sidebar/sidebar.component.ts | 82 +++++++++++-------- dmp-frontend/src/assets/config/config.json | 37 +++++++++ 5 files changed, 205 insertions(+), 64 deletions(-) create mode 100644 dmp-frontend/src/app/core/model/configuration-models/sidebar.model.ts diff --git a/dmp-frontend/src/app/core/model/configuration-models/sidebar.model.ts b/dmp-frontend/src/app/core/model/configuration-models/sidebar.model.ts new file mode 100644 index 000000000..691f71bef --- /dev/null +++ b/dmp-frontend/src/app/core/model/configuration-models/sidebar.model.ts @@ -0,0 +1,78 @@ + +export class Sidebar { + + private _infoItems: SidebarItem[]; + get infoItems(): SidebarItem[] { + return this._infoItems; + } + + private _footerItems: SidebarItem[]; + get footerItems(): SidebarItem[] { + return this._footerItems; + } + + public static parseValue(value: any): Sidebar { + const sidebarItemsObj: Sidebar = new Sidebar(); + + sidebarItemsObj._infoItems = []; + for (let infoItem of value.infoItems) { + const infoItemObj: SidebarItem = SidebarItem.parseValue(infoItem); + sidebarItemsObj._infoItems.push(infoItemObj); + } + + sidebarItemsObj._footerItems = []; + for (let footerItem of value.footerItems) { + const footerItemObj: SidebarItem = SidebarItem.parseValue(footerItem); + sidebarItemsObj._footerItems.push(footerItemObj); + } + + return sidebarItemsObj; + } +} + +export class SidebarItem { + private _routerPath: string; + get routerPath(): string { + return this._routerPath; + } + + private _title: string; + get title(): string { + return this._title; + } + + private _icon: string; + get icon(): string { + return this._icon; + } + + private _externalUrl?: string|null; + get externalUrl(): string|null { + return this._externalUrl; + } + + private _accessLevel: AccessLevel; + get accessLevel(): AccessLevel { + return this._accessLevel; + } + + get isExternalLink(): boolean { + return this.externalUrl != null && this.externalUrl != ''; + } + + public static parseValue(value: any): SidebarItem { + const obj: SidebarItem = new SidebarItem(); + obj._routerPath = value.routerPath; + obj._title = value.title; + obj._icon = value.icon; + obj._externalUrl = value.externalUrl; + obj._accessLevel = value.accessLevel ?? AccessLevel.Public; + return obj; + } +} + +export enum AccessLevel { + Authenticated = "authenticated", + Unauthenticated = "unauthenticated", + Public = "public", +} diff --git a/dmp-frontend/src/app/core/services/configuration/configuration.service.ts b/dmp-frontend/src/app/core/services/configuration/configuration.service.ts index e6b1e2cc4..0182501a7 100644 --- a/dmp-frontend/src/app/core/services/configuration/configuration.service.ts +++ b/dmp-frontend/src/app/core/services/configuration/configuration.service.ts @@ -12,6 +12,7 @@ import { Guid } from '@common/types/guid'; import { AuthProviders } from '@app/core/model/configuration-models/auth-providers.model'; import { AnalyticsProviders } from '@app/core/model/configuration-models/analytics-providers.model'; import { CssColorsTenantConfiguration } from '@app/core/model/tenant-configuaration/tenant-configuration'; +import { Sidebar } from '@app/core/model/configuration-models/sidebar.model'; @Injectable({ providedIn: 'root', @@ -161,6 +162,11 @@ export class ConfigurationService extends BaseComponent { return this._analyticsProviders; } + private _sidebar: Sidebar; + get sidebar(): Sidebar { + return this._sidebar; + } + private _researcherId: any; get researcherId(): boolean { return this._researcherId; @@ -259,6 +265,7 @@ export class ConfigurationService extends BaseComponent { this._newReleaseNotificationVersionCode = config.newReleaseNotification?.versionCode; this._authProviders = AuthProviders.parseValue(config.authProviders); this._analyticsProviders = AnalyticsProviders.parseValue(config.analytics); + this._sidebar = Sidebar.parseValue(config.sidebar); this._researcherId = config.referenceTypes.researcherId; this._grantId = config.referenceTypes.grantId; this._organizationId = config.referenceTypes.organizationId; diff --git a/dmp-frontend/src/app/ui/sidebar/sidebar.component.html b/dmp-frontend/src/app/ui/sidebar/sidebar.component.html index c761c0cf5..f60085aed 100644 --- a/dmp-frontend/src/app/ui/sidebar/sidebar.component.html +++ b/dmp-frontend/src/app/ui/sidebar/sidebar.component.html @@ -4,35 +4,42 @@

- - {{ groupMenuRoute.icon }} - person - {{groupMenuRoute.title | translate}} - - - - - - - {{ groupMenuRoute.icon }} - {{groupMenuRoute.title | translate}} open_in_new - - - {{ groupMenuRoute.icon }} - {{groupMenuRoute.title | translate}} - - - {{ groupMenuRoute.icon }} - {{groupMenuRoute.title | translate}} open_in_new - - - {{ groupMenuRoute.icon }} - {{groupMenuRoute.title | translate}} open_in_new - + + + + {{ groupMenuRoute.icon }} + person + {{groupMenuRoute.title | translate}} + + + + + + + + + + + + + + + {{ groupMenuRoute.icon }} + {{groupMenuRoute.title | translate}} + + + + + + {{ groupMenuRoute.icon }} + {{groupMenuRoute.title | translate}} open_in_new + + +
diff --git a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts index e4ef8af3b..7e5521fcf 100644 --- a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts +++ b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts @@ -10,14 +10,21 @@ import { AuthService } from '../../core/services/auth/auth.service'; import { LanguageDialogComponent } from '../language/dialog/language-dialog.component'; import { UserDialogComponent } from '../navbar/user-dialog/user-dialog.component'; import { RouterUtilsService } from '@app/core/services/router/router-utils.service'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { AccessLevel } from '@app/core/model/configuration-models/sidebar.model'; +enum RouteType { + System = 0, + Configurable = 1, +} declare interface RouteInfo { path: string; title: string; icon: string; - url?: string; + externalUrl?: string; + routeType: RouteType; } -declare interface GroupMenuItem { +class GroupMenuItem { title: string; routes: RouteInfo[]; } @@ -37,6 +44,7 @@ export class SidebarComponent implements OnInit { infoItems: GroupMenuItem; groupMenuItems: GroupMenuItem[] = []; currentRoute: string; + routeType = RouteType; constructor( public translate: TranslateService, @@ -46,6 +54,7 @@ export class SidebarComponent implements OnInit { private location: Location, private analyticsService: AnalyticsService, public routerUtils: RouterUtilsService, + private configurationService: ConfigurationService, ) { } ngOnInit() { @@ -68,7 +77,7 @@ export class SidebarComponent implements OnInit { title: 'SIDE-BAR.GENERAL', routes: [], } - this.generalItems.routes.push({ path: '/home', title: 'SIDE-BAR.DASHBOARD', icon: 'home' }); + this.generalItems.routes.push({ path: '/home', title: 'SIDE-BAR.DASHBOARD', icon: 'home', routeType: RouteType.System }); this.groupMenuItems.push(this.generalItems); @@ -77,8 +86,8 @@ export class SidebarComponent implements OnInit { routes: [], } - if (this.authentication.hasPermission(AppPermission.ViewMyDmpPage)) this.dmpItems.routes.push({ path: '/plans', title: 'SIDE-BAR.MY-DMPS', icon: 'library_books' }); - if (this.authentication.hasPermission(AppPermission.ViewMyDescriptionPage)) this.dmpItems.routes.push({ path: '/descriptions', title: 'SIDE-BAR.MY-DESCRIPTIONS', icon: 'dns' }); + if (this.authentication.hasPermission(AppPermission.ViewMyDmpPage)) this.dmpItems.routes.push({ path: '/plans', title: 'SIDE-BAR.MY-DMPS', icon: 'library_books', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewMyDescriptionPage)) this.dmpItems.routes.push({ path: '/descriptions', title: 'SIDE-BAR.MY-DESCRIPTIONS', icon: 'dns', routeType: RouteType.System }); this.groupMenuItems.push(this.dmpItems); this.descriptionItems = { @@ -86,8 +95,8 @@ export class SidebarComponent implements OnInit { routes: [], } - if (this.authentication.hasPermission(AppPermission.ViewPublicDmpPage)) this.descriptionItems.routes.push({ path: '/explore-plans', title: 'SIDE-BAR.PUBLIC-DMPS', icon: 'library_books' }); - if (this.authentication.hasPermission(AppPermission.ViewPublicDescriptionPage)) this.descriptionItems.routes.push({ path: '/explore-descriptions', title: 'SIDE-BAR.PUBLIC-DESC', icon: 'dns' }); + if (this.authentication.hasPermission(AppPermission.ViewPublicDmpPage)) this.descriptionItems.routes.push({ path: '/explore-plans', title: 'SIDE-BAR.PUBLIC-DMPS', icon: 'library_books', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewPublicDescriptionPage)) this.descriptionItems.routes.push({ path: '/explore-descriptions', title: 'SIDE-BAR.PUBLIC-DESC', icon: 'dns', routeType: RouteType.System }); this.groupMenuItems.push(this.descriptionItems); this.publicItems = { @@ -95,8 +104,8 @@ export class SidebarComponent implements OnInit { routes: [], } if (!this.isAuthenticated()) { - this.publicItems.routes.push({ path: '/explore-plans', title: 'SIDE-BAR.PUBLIC-DMPS', icon: 'library_books' }); - this.publicItems.routes.push({ path: '/explore-descriptions', title: 'SIDE-BAR.PUBLIC-DESC', icon: 'dns' }); + this.publicItems.routes.push({ path: '/explore-plans', title: 'SIDE-BAR.PUBLIC-DMPS', icon: 'library_books', routeType: RouteType.System }); + this.publicItems.routes.push({ path: '/explore-descriptions', title: 'SIDE-BAR.PUBLIC-DESC', icon: 'dns', routeType: RouteType.System }); } this.groupMenuItems.push(this.publicItems); @@ -104,32 +113,40 @@ export class SidebarComponent implements OnInit { title: 'SIDE-BAR.ADMIN', routes: [], } - if (this.authentication.hasPermission(AppPermission.ViewDmpBlueprintPage)) this.adminItems.routes.push({ path: '/dmp-blueprints', title: 'SIDE-BAR.DMP-BLUEPRINTS', icon: 'library_books' }); - if (this.authentication.hasPermission(AppPermission.ViewDescriptionTemplatePage)) this.adminItems.routes.push({ path: '/description-templates', title: 'SIDE-BAR.DESCRIPTION-TEMPLATES', icon: 'description' }); - if (this.authentication.hasPermission(AppPermission.ViewDescriptionTemplateTypePage)) this.adminItems.routes.push({ path: '/description-template-type', title: 'SIDE-BAR.DESCRIPTION-TEMPLATE-TYPES', icon: 'stack' }); - if (this.authentication.hasPermission(AppPermission.ViewEntityLockPage)) this.adminItems.routes.push({ path: '/entity-locks', title: 'SIDE-BAR.ENTITY-LOCKS', icon: 'lock_person' }); - if (this.authentication.hasPermission(AppPermission.ViewReferencePage)) this.adminItems.routes.push({ path: '/references', title: 'SIDE-BAR.REFERENCES', icon: 'dataset_linked' }); - if (this.authentication.hasPermission(AppPermission.ViewReferenceTypePage)) this.adminItems.routes.push({ path: '/reference-type', title: 'SIDE-BAR.REFERENCE-TYPES', icon: 'add_link' }); - if (this.authentication.hasPermission(AppPermission.ViewPrefillingSourcePage)) this.adminItems.routes.push({ path: '/prefilling-sources', title: 'SIDE-BAR.PREFILLING-SOURCES', icon: 'quick_reference_all' }); - if (this.authentication.hasPermission(AppPermission.ViewTenantPage)) this.adminItems.routes.push({ path: '/tenants', title: 'SIDE-BAR.TENANTS', icon: 'tenancy' }); - if (this.authentication.hasPermission(AppPermission.ViewTenantConfigurationPage)) this.adminItems.routes.push({ path: '/tenant-configuration', title: 'SIDE-BAR.TENANT-CONFIGURATION', icon: 'settings' }); - if (this.authentication.hasPermission(AppPermission.ViewUserPage)) this.adminItems.routes.push({ path: '/users', title: 'SIDE-BAR.USERS', icon: 'people' }); - if (this.authentication.hasPermission(AppPermission.ViewTenantUserPage)) this.adminItems.routes.push({ path: '/tenant-users', title: 'SIDE-BAR.TENANT-USERS', icon: 'people' }); - if (this.authentication.hasPermission(AppPermission.ViewLanguagePage)) this.adminItems.routes.push({ path: '/languages', title: 'SIDE-BAR.LANGUAGES', icon: 'language' }); - if (this.authentication.hasPermission(AppPermission.ViewSupportiveMaterialPage)) this.adminItems.routes.push({ path: '/supportive-material', title: 'SIDE-BAR.SUPPORTIVE-MATERIAL', icon: 'help_center' }); - if (this.authentication.hasPermission(AppPermission.ViewNotificationTemplatePage)) this.adminItems.routes.push({ path: '/notification-templates', title: 'SIDE-BAR.NOTIFICATION-TEMPLATES', icon: 'grid_guides' }); - if (this.authentication.hasPermission(AppPermission.ViewNotificationPage)) this.adminItems.routes.push({ path: '/notifications', title: 'SIDE-BAR.NOTIFICATIONS', icon: 'notifications' }); - if (this.authentication.hasPermission(AppPermission.ViewStatusPage)) this.adminItems.routes.push({ path: '/annotation-statuses', title: 'SIDE-BAR.ANNOTATION-STATUSES', icon: 'notifications' }); - if (this.authentication.hasPermission(AppPermission.ViewMaintenancePage)) this.adminItems.routes.push({ path: '/maintenance-tasks', title: 'SIDE-BAR.MAINTENANCE', icon: 'build' }); + if (this.authentication.hasPermission(AppPermission.ViewDmpBlueprintPage)) this.adminItems.routes.push({ path: '/dmp-blueprints', title: 'SIDE-BAR.DMP-BLUEPRINTS', icon: 'library_books', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewDescriptionTemplatePage)) this.adminItems.routes.push({ path: '/description-templates', title: 'SIDE-BAR.DESCRIPTION-TEMPLATES', icon: 'description', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewDescriptionTemplateTypePage)) this.adminItems.routes.push({ path: '/description-template-type', title: 'SIDE-BAR.DESCRIPTION-TEMPLATE-TYPES', icon: 'stack', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewEntityLockPage)) this.adminItems.routes.push({ path: '/entity-locks', title: 'SIDE-BAR.ENTITY-LOCKS', icon: 'lock_person', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewReferencePage)) this.adminItems.routes.push({ path: '/references', title: 'SIDE-BAR.REFERENCES', icon: 'dataset_linked', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewReferenceTypePage)) this.adminItems.routes.push({ path: '/reference-type', title: 'SIDE-BAR.REFERENCE-TYPES', icon: 'add_link', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewPrefillingSourcePage)) this.adminItems.routes.push({ path: '/prefilling-sources', title: 'SIDE-BAR.PREFILLING-SOURCES', icon: 'quick_reference_all', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewTenantPage)) this.adminItems.routes.push({ path: '/tenants', title: 'SIDE-BAR.TENANTS', icon: 'tenancy', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewTenantConfigurationPage)) this.adminItems.routes.push({ path: '/tenant-configuration', title: 'SIDE-BAR.TENANT-CONFIGURATION', icon: 'settings', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewUserPage)) this.adminItems.routes.push({ path: '/users', title: 'SIDE-BAR.USERS', icon: 'people', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewTenantUserPage)) this.adminItems.routes.push({ path: '/tenant-users', title: 'SIDE-BAR.TENANT-USERS', icon: 'people', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewLanguagePage)) this.adminItems.routes.push({ path: '/languages', title: 'SIDE-BAR.LANGUAGES', icon: 'language', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewSupportiveMaterialPage)) this.adminItems.routes.push({ path: '/supportive-material', title: 'SIDE-BAR.SUPPORTIVE-MATERIAL', icon: 'help_center', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewNotificationTemplatePage)) this.adminItems.routes.push({ path: '/notification-templates', title: 'SIDE-BAR.NOTIFICATION-TEMPLATES', icon: 'grid_guides', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewNotificationPage)) this.adminItems.routes.push({ path: '/notifications', title: 'SIDE-BAR.NOTIFICATIONS', icon: 'notifications', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewStatusPage)) this.adminItems.routes.push({ path: '/annotation-statuses', title: 'SIDE-BAR.ANNOTATION-STATUSES', icon: 'notifications', routeType: RouteType.System }); + if (this.authentication.hasPermission(AppPermission.ViewMaintenancePage)) this.adminItems.routes.push({ path: '/maintenance-tasks', title: 'SIDE-BAR.MAINTENANCE', icon: 'build', routeType: RouteType.System }); this.groupMenuItems.push(this.adminItems); + let infoItems: RouteInfo[] = this.configurationService?.sidebar?.infoItems.map(infoItem => { + if (infoItem.accessLevel == AccessLevel.Authenticated && !this.isAuthenticated()) return null; + if (infoItem.accessLevel == AccessLevel.Unauthenticated && this.isAuthenticated()) return null; + + if (infoItem.isExternalLink) { + return { title: infoItem.title, icon: infoItem.icon, externalUrl: infoItem.externalUrl, routeType: RouteType.Configurable } as RouteInfo; + } else { + return { title: infoItem.title, icon: infoItem.icon, path: infoItem.routerPath, routeType: RouteType.Configurable } as RouteInfo; + } + })?.filter(x => x!=null); this.infoItems = { title: "", - routes: [], + routes: infoItems ?? [] } - this.infoItems.routes.push({ path: '/co-branding', title: 'SIDE-BAR.CO-BRANDING', icon: 'toll' }); - this.infoItems.routes.push({ path: '/contact-support', title: 'SIDE-BAR.SUPPORT', icon: 'help' }); - this.infoItems.routes.push({ path: '/feedback', title: 'SIDE-BAR.FEEDBACK', icon: 'feedback', url: 'https://docs.google.com/forms/d/12RSCrUjdSDp2LZLpjDKOi44cN1fLDD2q1-F66SqZIis/viewform?edit_requested=true' }); + this.groupMenuItems.push(this.infoItems); } @@ -189,9 +206,4 @@ export class SidebarComponent implements OnInit { }); } } - - public openFeedback(groupMenuRoute: RouteInfo) { - window.open(groupMenuRoute.url, '_blank'); - } - } diff --git a/dmp-frontend/src/assets/config/config.json b/dmp-frontend/src/assets/config/config.json index c6860fd7e..cee52e543 100644 --- a/dmp-frontend/src/assets/config/config.json +++ b/dmp-frontend/src/assets/config/config.json @@ -79,5 +79,42 @@ }, "deposit":{ "recordUrlIdPlaceholder": "{doi_id}" + }, + "sidebar": { + "infoItems": [ + { + "title": "SIDE-BAR.CO-BRANDING", + "icon": "toll", + "externalUrl": "/splash/resources/co-branding.html", + "accessLevel": "public" + }, + { + "title": "SIDE-BAR.SUPPORT", + "icon": "help", + "routerPath": "/contact-support", + "accessLevel": "authenticated" + }, + { + "title": "SIDE-BAR.SUPPORT", + "icon": "help", + "externalUrl": "/splash/contact.html", + "accessLevel": "unauthenticated" + }, + { + "title": "SIDE-BAR.FEEDBACK", + "icon": "feedback", + "externalUrl": "https://docs.google.com/forms/d/12RSCrUjdSDp2LZLpjDKOi44cN1fLDD2q1-F66SqZIis/viewform?edit_requested=true", + "accessLevel": "public" + } + ], + "footerItems": [ + { + "routerPath": "/feedback", + "title": "SIDE-BAR.FEEDBACK", + "icon": "feedback", + "externalUrl": "https://docs.google.com/forms/d/12RSCrUjdSDp2LZLpjDKOi44cN1fLDD2q1-F66SqZIis/viewform?edit_requested=true", + "accessLevel": true + } + ] } }