UI: Home links refactoring.
This commit is contained in:
parent
4a5dabdad8
commit
72134abbf9
@ -38,15 +38,14 @@ export interface MenuReference {
|
||||
pages?: Array<MenuReference>;
|
||||
}
|
||||
|
||||
export interface HomeSection {
|
||||
export interface HomeSectionReference {
|
||||
name: string;
|
||||
places: Array<HomeSectionPlace>;
|
||||
places: Array<MenuId>;
|
||||
}
|
||||
|
||||
export interface HomeSectionPlace {
|
||||
export interface HomeSection {
|
||||
name: string;
|
||||
icon: string;
|
||||
path: string;
|
||||
places: Array<MenuSection>;
|
||||
}
|
||||
|
||||
export enum MenuId {
|
||||
@ -768,11 +767,108 @@ const defaultUserMenuMap = new Map<Authority, MenuReference[]>([
|
||||
]
|
||||
]);
|
||||
|
||||
const defaultHomeSectionMap = new Map<Authority, HomeSectionReference[]>([
|
||||
[
|
||||
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<MenuSection> => {
|
||||
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<HomeSection> => {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
@ -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<MenuSection>;
|
||||
private menuSections$: Subject<Array<MenuSection>> = new ReplaySubject<Array<MenuSection>>(1);
|
||||
private homeSections$: Subject<Array<HomeSection>> = new BehaviorSubject<Array<HomeSection>>([]);
|
||||
private homeSections$: Subject<Array<HomeSection>> = new ReplaySubject<Array<HomeSection>>(1);
|
||||
private availableMenuSections$: Subject<Array<MenuSection>> = new ReplaySubject<Array<MenuSection>>(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<AppState>,
|
||||
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<HomeSection>;
|
||||
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<HomeSection> {
|
||||
const homeSections: Array<HomeSection> = [];
|
||||
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<HomeSection> {
|
||||
const homeSections: Array<HomeSection> = [];
|
||||
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<HomeSection> {
|
||||
const homeSections: Array<HomeSection> = [];
|
||||
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<MenuSection>): Array<MenuSection> {
|
||||
const result: Array<MenuSection> = [];
|
||||
for (const section of sections) {
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
<mat-grid-tile *ngFor="let place of sectionPlaces(section)">
|
||||
<a mat-raised-button color="primary" class="tb-card-button" href="{{place.path}}" (click)="navigate($event, place.path)">
|
||||
<tb-icon matButtonIcon class="tb-mat-96">{{place.icon}}</tb-icon>
|
||||
<span translate>{{place.name}}</span>
|
||||
<span>{{place.customTranslate ? (place.name | customTranslate) : (place.name | translate)}}</span>
|
||||
</a>
|
||||
</mat-grid-tile>
|
||||
</mat-grid-list>
|
||||
|
||||
@ -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') {
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
<mat-grid-tile *ngFor="let place of section.places">
|
||||
<a mat-raised-button color="primary" class="tb-card-button" routerLink="{{place.path}}">
|
||||
<tb-icon matButtonIcon class="tb-mat-96">{{place.icon}}</tb-icon>
|
||||
<span translate>{{place.name}}</span>
|
||||
<span>{{place.customTranslate ? (place.name | customTranslate) : (place.name | translate)}}</span>
|
||||
</a>
|
||||
</mat-grid-tile>
|
||||
</mat-grid-list>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user