diff --git a/ui-ngx/src/app/core/services/menu.models.ts b/ui-ngx/src/app/core/services/menu.models.ts index 7afe08f929..e27d015fbe 100644 --- a/ui-ngx/src/app/core/services/menu.models.ts +++ b/ui-ngx/src/app/core/services/menu.models.ts @@ -38,15 +38,14 @@ export interface MenuReference { pages?: Array; } -export interface HomeSection { +export interface HomeSectionReference { name: string; - places: Array; + places: Array; } -export interface HomeSectionPlace { +export interface HomeSection { name: string; - icon: string; - path: string; + places: Array; } export enum MenuId { @@ -768,11 +767,108 @@ const defaultUserMenuMap = new Map([ ] ]); +const defaultHomeSectionMap = new Map([ + [ + Authority.SYS_ADMIN, + [ + { + name: 'tenant.management', + places: [MenuId.tenants, MenuId.tenant_profiles] + }, + { + name: 'widget.management', + places: [MenuId.widget_library] + }, + { + name: 'admin.system-settings', + places: [MenuId.general, MenuId.mail_server, + MenuId.notification_settings, MenuId.security_settings, MenuId.oauth2, MenuId.two_fa, MenuId.resources_library, MenuId.queues] + } + ] + ], + [ + Authority.TENANT_ADMIN, + [ + { + name: 'rulechain.management', + places: [MenuId.rule_chains] + }, + { + name: 'customer.management', + places: [MenuId.customers] + }, + { + name: 'asset.management', + places: [MenuId.assets, MenuId.asset_profiles] + }, + { + name: 'device.management', + places: [MenuId.devices, MenuId.device_profiles, MenuId.otaUpdates] + }, + { + name: 'entity-view.management', + places: [MenuId.entity_views] + }, + { + name: 'edge.management', + places: [MenuId.edges, MenuId.rulechain_templates] + }, + { + name: 'dashboard.management', + places: [MenuId.widget_library, MenuId.dashboards] + }, + { + name: 'version-control.management', + places: [MenuId.version_control] + }, + { + name: 'audit-log.audit', + places: [MenuId.audit_log, MenuId.api_usage] + }, + { + name: 'admin.system-settings', + places: [MenuId.home_settings, MenuId.resources_library, MenuId.repository_settings, MenuId.auto_commit_settings] + } + ] + ], + [ + Authority.CUSTOMER_USER, + [ + { + name: 'asset.view-assets', + places: [MenuId.assets] + }, + { + name: 'device.view-devices', + places: [MenuId.devices] + }, + { + name: 'entity-view.management', + places: [MenuId.entity_views] + }, + { + name: 'edge.management', + places: [MenuId.edges] + }, + { + name: 'dashboard.view-dashboards', + places: [MenuId.dashboards] + } + ] + ] +]); + export const buildUserMenu = (authState: AuthState): Array => { const references = defaultUserMenuMap.get(authState.authUser.authority); return (references || []).map(ref => referenceToMenuSection(authState, ref)).filter(section => !!section); }; +export const buildUserHome = (authState: AuthState, availableMenuSections: MenuSection[]): Array => { + const references = defaultHomeSectionMap.get(authState.authUser.authority); + return (references || []).map(ref => + homeReferenceToHomeSection(availableMenuSections, ref)).filter(section => !!section); +}; + const referenceToMenuSection = (authState: AuthState, reference: MenuReference): MenuSection | undefined => { if (filterMenuReference(authState, reference)) { const section = menuSectionMap.get(reference.id); @@ -807,3 +903,15 @@ const filterMenuReference = (authState: AuthState, reference: MenuReference): bo return true; } }; + +const homeReferenceToHomeSection = (availableMenuSections: MenuSection[], reference: HomeSectionReference): HomeSection | undefined => { + const places = reference.places.map(id => availableMenuSections.find(m => m.id === id)).filter(p => !!p); + if (places.length) { + return { + name: reference.name, + places + }; + } else { + return undefined; + } +}; diff --git a/ui-ngx/src/app/core/services/menu.service.ts b/ui-ngx/src/app/core/services/menu.service.ts index cfa555d627..90976e282c 100644 --- a/ui-ngx/src/app/core/services/menu.service.ts +++ b/ui-ngx/src/app/core/services/menu.service.ts @@ -19,9 +19,8 @@ import { select, Store } from '@ngrx/store'; import { AppState } from '../core.state'; import { getCurrentOpenedMenuSections, selectAuth, selectIsAuthenticated } from '../auth/auth.selectors'; import { filter, map, take } from 'rxjs/operators'; -import { buildUserMenu, HomeSection, MenuId, MenuSection } from '@core/services/menu.models'; -import { BehaviorSubject, ReplaySubject, Observable, Subject } from 'rxjs'; -import { Authority } from '@shared/models/authority.enum'; +import { buildUserHome, buildUserMenu, HomeSection, MenuId, MenuSection } from '@core/services/menu.models'; +import { Observable, ReplaySubject, Subject } from 'rxjs'; import { AuthState } from '@core/auth/auth.models'; import { NavigationEnd, Router } from '@angular/router'; @@ -32,13 +31,11 @@ export class MenuService { private currentMenuSections: Array; private menuSections$: Subject> = new ReplaySubject>(1); - private homeSections$: Subject> = new BehaviorSubject>([]); + private homeSections$: Subject> = new ReplaySubject>(1); + private availableMenuSections$: Subject> = new ReplaySubject>(1); private availableMenuLinks$ = this.menuSections$.pipe( map((items) => this.allMenuLinks(items)) ); - private availableMenuSections$ = this.menuSections$.pipe( - map((items) => this.allMenuSections(items)) - ); constructor(private store: Store, private router: Router) { @@ -60,21 +57,12 @@ export class MenuService { this.store.pipe(select(selectAuth), take(1)).subscribe( (authState: AuthState) => { if (authState.authUser) { - let homeSections: Array; - switch (authState.authUser.authority) { - case Authority.SYS_ADMIN: - homeSections = this.buildSysAdminHome(); - break; - case Authority.TENANT_ADMIN: - homeSections = this.buildTenantAdminHome(authState); - break; - case Authority.CUSTOMER_USER: - homeSections = this.buildCustomerUserHome(authState); - break; - } this.currentMenuSections = buildUserMenu(authState); this.updateOpenedMenuSections(); this.menuSections$.next(this.currentMenuSections); + const availableMenuSections = this.allMenuSections(this.currentMenuSections); + this.availableMenuSections$.next(availableMenuSections); + const homeSections = buildUserHome(authState, availableMenuSections); this.homeSections$.next(homeSections); } } @@ -90,304 +78,6 @@ export class MenuService { ); } - private buildSysAdminHome(): Array { - const homeSections: Array = []; - homeSections.push( - { - name: 'tenant.management', - places: [ - { - name: 'tenant.tenants', - icon: 'supervisor_account', - path: '/tenants' - }, - { - name: 'tenant-profile.tenant-profiles', - icon: 'mdi:alpha-t-box', - path: '/tenantProfiles' - }, - ] - }, - { - name: 'widget.management', - places: [ - { - name: 'widget.widget-library', - icon: 'now_widgets', - path: '/resources/widgets-library', - } - ] - }, - { - name: 'admin.system-settings', - places: [ - { - name: 'admin.general', - icon: 'settings_applications', - path: '/settings/general' - }, - { - name: 'admin.outgoing-mail', - icon: 'mail', - path: '/settings/outgoing-mail' - }, - { - name: 'admin.sms-provider', - icon: 'sms', - path: '/settings/sms-provider' - }, - { - name: 'admin.security-settings', - icon: 'security', - path: '/settings/security-settings' - }, - { - name: 'admin.oauth2.oauth2', - icon: 'security', - path: '/settings/oauth2' - }, - { - name: 'admin.2fa.2fa', - icon: 'mdi:two-factor-authentication', - path: '/settings/2fa' - }, - { - name: 'resource.resources-library', - icon: 'folder', - path: '/settings/resources-library' - }, - { - name: 'admin.queues', - icon: 'swap_calls', - path: '/settings/queues' - }, - ] - } - ); - return homeSections; - } - - private buildTenantAdminHome(authState: AuthState): Array { - const homeSections: Array = []; - homeSections.push( - { - name: 'rulechain.management', - places: [ - { - name: 'rulechain.rulechains', - icon: 'settings_ethernet', - path: '/ruleChains' - } - ] - }, - { - name: 'customer.management', - places: [ - { - name: 'customer.customers', - icon: 'supervisor_account', - path: '/customers' - } - ] - }, - { - name: 'asset.management', - places: [ - { - name: 'asset.assets', - icon: 'domain', - path: '/assets' - }, - { - name: 'asset-profile.asset-profiles', - icon: 'mdi:alpha-a-box', - path: '/profiles/assetProfiles' - } - ] - }, - { - name: 'device.management', - places: [ - { - name: 'device.devices', - icon: 'devices_other', - path: '/devices' - }, - { - name: 'device-profile.device-profiles', - icon: 'mdi:alpha-d-box', - path: '/profiles/deviceProfiles' - }, - { - name: 'ota-update.ota-updates', - icon: 'memory', - path: '/otaUpdates' - } - ] - }, - { - name: 'entity-view.management', - places: [ - { - name: 'entity-view.entity-views', - icon: 'view_quilt', - path: '/entityViews' - } - ] - } - ); - if (authState.edgesSupportEnabled) { - homeSections.push( - { - name: 'edge.management', - places: [ - { - name: 'edge.edge-instances', - icon: 'router', - path: '/edgeInstances' - }, - { - name: 'edge.rulechain-templates', - icon: 'settings_ethernet', - path: '/edgeManagement/ruleChains' - } - ] - } - ); - } - homeSections.push( - { - name: 'dashboard.management', - places: [ - { - name: 'widget.widget-library', - icon: 'now_widgets', - path: '/widgets-bundles' - }, - { - name: 'dashboard.dashboards', - icon: 'dashboard', - path: '/dashboards' - } - ] - }, - { - name: 'version-control.management', - places: [ - { - name: 'version-control.version-control', - icon: 'history', - path: '/vc' - } - ] - }, - { - name: 'audit-log.audit', - places: [ - { - name: 'audit-log.audit-logs', - icon: 'track_changes', - path: '/auditLogs' - }, - { - name: 'api-usage.api-usage', - icon: 'insert_chart', - path: '/usage' - } - ] - }, - { - name: 'admin.system-settings', - places: [ - { - name: 'admin.home-settings', - icon: 'settings_applications', - path: '/settings/home' - }, - { - name: 'resource.resources-library', - icon: 'folder', - path: '/settings/resources-library' - }, - { - name: 'admin.repository-settings', - icon: 'manage_history', - path: '/settings/repository', - }, - { - name: 'admin.auto-commit-settings', - icon: 'settings_backup_restore', - path: '/settings/auto-commit' - } - ] - } - ); - return homeSections; - } - - private buildCustomerUserHome(authState: AuthState): Array { - const homeSections: Array = []; - homeSections.push( - { - name: 'asset.view-assets', - places: [ - { - name: 'asset.assets', - icon: 'domain', - path: '/assets' - } - ] - }, - { - name: 'device.view-devices', - places: [ - { - name: 'device.devices', - icon: 'devices_other', - path: '/devices' - } - ] - }, - { - name: 'entity-view.management', - places: [ - { - name: 'entity-view.entity-views', - icon: 'view_quilt', - path: '/entityViews' - } - ] - } - ); - if (authState.edgesSupportEnabled) { - homeSections.push( - { - name: 'edge.management', - places: [ - { - name: 'edge.edge-instances', - icon: 'settings_input_antenna', - path: '/edgeInstances' - } - ] - } - ); - } - homeSections.push( - { - name: 'dashboard.view-dashboards', - places: [ - { - name: 'dashboard.dashboards', - icon: 'dashboard', - path: '/dashboards' - } - ] - } - ); - return homeSections; - } - private allMenuLinks(sections: Array): Array { const result: Array = []; for (const section of sections) { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/navigation-cards-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/navigation-cards-widget.component.html index 72b154d89a..0d59ed8564 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/navigation-cards-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/navigation-cards-widget.component.html @@ -26,7 +26,7 @@ {{place.icon}} - {{place.name}} + {{place.customTranslate ? (place.name | customTranslate) : (place.name | translate)}} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/navigation-cards-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/navigation-cards-widget.component.ts index 8ff8fa74e9..539b77f34a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/navigation-cards-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/navigation-cards-widget.component.ts @@ -20,7 +20,7 @@ import { WidgetContext } from '@home/models/widget-component.models'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { MenuService } from '@core/services/menu.service'; -import { HomeSection, HomeSectionPlace } from '@core/services/menu.models'; +import { HomeSection, MenuSection } from '@core/services/menu.models'; import { Router } from '@angular/router'; import { map } from 'rxjs/operators'; @@ -38,9 +38,7 @@ export class NavigationCardsWidgetComponent extends PageComponent implements OnI homeSections$ = this.menuService.homeSections(); showHomeSections$ = this.homeSections$.pipe( - map((sections) => { - return sections.filter((section) => this.sectionPlaces(section).length > 0); - }) + map((sections) => sections.filter((section) => this.sectionPlaces(section).length > 0)) ); cols = null; @@ -85,11 +83,11 @@ export class NavigationCardsWidgetComponent extends PageComponent implements OnI }); } - sectionPlaces(section: HomeSection): HomeSectionPlace[] { + sectionPlaces(section: HomeSection): MenuSection[] { return section && section.places ? section.places.filter((place) => this.filterPlace(place)) : []; } - private filterPlace(place: HomeSectionPlace): boolean { + private filterPlace(place: MenuSection): boolean { if (this.settings.filterType === 'include') { return this.settings.filter.includes(place.path); } else if (this.settings.filterType === 'exclude') { diff --git a/ui-ngx/src/app/modules/home/pages/home-links/home-links.component.html b/ui-ngx/src/app/modules/home/pages/home-links/home-links.component.html index 132d0e2c65..81142c501f 100644 --- a/ui-ngx/src/app/modules/home/pages/home-links/home-links.component.html +++ b/ui-ngx/src/app/modules/home/pages/home-links/home-links.component.html @@ -28,7 +28,7 @@ {{place.icon}} - {{place.name}} + {{place.customTranslate ? (place.name | customTranslate) : (place.name | translate)}}