committed by
GitHub
101 changed files with 1959 additions and 570 deletions
@ -0,0 +1,42 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { Injectable } from '@angular/core'; |
|||
import { Actions, createEffect, ofType } from '@ngrx/effects'; |
|||
import { select, Store } from '@ngrx/store'; |
|||
import { AppState } from '@core/core.state'; |
|||
import { UserSettingsService } from '@core/http/user-settings.service'; |
|||
import { mergeMap, withLatestFrom } from 'rxjs/operators'; |
|||
import { AuthActions, AuthActionTypes } from '@core/auth/auth.actions'; |
|||
import { selectAuthState } from '@core/auth/auth.selectors'; |
|||
|
|||
@Injectable() |
|||
export class AuthEffects { |
|||
constructor( |
|||
private actions$: Actions<AuthActions>, |
|||
private store: Store<AppState>, |
|||
private userSettingsService: UserSettingsService |
|||
) { |
|||
} |
|||
|
|||
persistOpenedMenuSections = createEffect(() => this.actions$.pipe( |
|||
ofType( |
|||
AuthActionTypes.UPDATE_OPENED_MENU_SECTION, |
|||
), |
|||
withLatestFrom(this.store.pipe(select(selectAuthState))), |
|||
mergeMap(([action, state]) => this.userSettingsService.putUserSettings({ openedMenuSections: state.userSettings.openedMenuSections })) |
|||
), {dispatch: false}); |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { Injectable } from '@angular/core'; |
|||
import { Observable } from 'rxjs'; |
|||
import { initialUserSettings, UserSettings } from '@shared/models/user-settings.models'; |
|||
import { map } from 'rxjs/operators'; |
|||
import { HttpClient } from '@angular/common/http'; |
|||
import { defaultHttpOptionsFromConfig } from '@core/http/http-utils'; |
|||
|
|||
@Injectable({ |
|||
providedIn: 'root' |
|||
}) |
|||
export class UserSettingsService { |
|||
|
|||
constructor( |
|||
private http: HttpClient |
|||
) {} |
|||
|
|||
public loadUserSettings(): Observable<UserSettings> { |
|||
return this.http.get<UserSettings>('/api/user/settings', defaultHttpOptionsFromConfig({ignoreLoading: true, ignoreErrors: true})).pipe( |
|||
map((settings) => (!settings || !Object.keys(settings).length) ? initialUserSettings : settings) |
|||
); |
|||
} |
|||
|
|||
public saveUserSettings(userSettings: UserSettings): Observable<UserSettings> { |
|||
return this.http.post<UserSettings>('/api/user/settings', userSettings, |
|||
defaultHttpOptionsFromConfig({ignoreLoading: true, ignoreErrors: true})); |
|||
} |
|||
|
|||
public putUserSettings(userSettingsData: Partial<UserSettings>): Observable<void> { |
|||
return this.http.put<void>('/api/user/settings', userSettingsData, |
|||
defaultHttpOptionsFromConfig({ignoreLoading: true, ignoreErrors: true})); |
|||
} |
|||
|
|||
public deleteUserSettings(paths: string[]) { |
|||
return this.http.delete(`/api/user/settings/${paths.join(',')}`, |
|||
defaultHttpOptionsFromConfig({ignoreLoading: true, ignoreErrors: true})); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { Injectable } from '@angular/core'; |
|||
import { Observable, Subject } from 'rxjs'; |
|||
|
|||
@Injectable({ |
|||
providedIn: 'root' |
|||
}) |
|||
export class ActiveComponentService { |
|||
|
|||
private activeComponent: any; |
|||
private activeComponentChangedSubject: Subject<any> = new Subject<any>(); |
|||
|
|||
public getCurrentActiveComponent(): any { |
|||
return this.activeComponent; |
|||
} |
|||
|
|||
public setCurrentActiveComponent(component: any): void { |
|||
this.activeComponent = component; |
|||
this.activeComponentChangedSubject.next(component); |
|||
} |
|||
|
|||
public onActiveComponentChanged(): Observable<any> { |
|||
return this.activeComponentChangedSubject.asObservable(); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
<!-- |
|||
|
|||
Copyright © 2016-2023 The Thingsboard Authors |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); |
|||
you may not use this file except in compliance with the License. |
|||
You may obtain a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, |
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
See the License for the specific language governing permissions and |
|||
limitations under the License. |
|||
|
|||
--> |
|||
<div fxFlex fxLayout="column" style="width: 100%;"> |
|||
<nav *ngIf="!routerOutlet?.activatedRouteData?.hideTabs && !hideCurrentTabs && (tabs$ | async).length > 1" mat-tab-nav-bar mat-stretch-tabs="false" class="tb-router-tabs" [tabPanel]="tabPanel"> |
|||
<a *ngFor="let tab of tabs$ | async" |
|||
routerLink="{{tab.path}}" |
|||
routerLinkActive |
|||
#rla="routerLinkActive" |
|||
mat-tab-link |
|||
[active]="rla.isActive"> |
|||
<mat-icon *ngIf="!tab.isMdiIcon && tab.icon !== null" class="tb-mat-18">{{tab.icon}}</mat-icon> |
|||
<mat-icon *ngIf="tab.isMdiIcon && tab.icon !== null" [svgIcon]="tab.icon" class="tb-mat-18"></mat-icon> |
|||
<span>{{tab.name | translate}}</span> |
|||
</a> |
|||
</nav> |
|||
<mat-tab-nav-panel #tabPanel fxFlex fxLayout="column" class="tb-router-tabs-content"> |
|||
<router-outlet #routerOutlet="outlet" (activate)="activeComponentChanged($event)"></router-outlet> |
|||
</mat-tab-nav-panel> |
|||
</div> |
|||
@ -0,0 +1,46 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0 |
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
:host { |
|||
display: flex; |
|||
width: 100%; |
|||
height: 100%; |
|||
|
|||
.mat-mdc-tab-nav-bar.tb-router-tabs { |
|||
a.mat-mdc-tab-link { |
|||
display: inline-flex; |
|||
align-items: center; |
|||
overflow: hidden; |
|||
line-height: 40px; |
|||
min-width: 200px; |
|||
border-bottom: none; |
|||
mat-icon { |
|||
margin-right: 8px; |
|||
margin-left: 0; |
|||
} |
|||
span { |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.tb-router-tabs-content { |
|||
overflow: auto; |
|||
position: relative; |
|||
height: 100%; |
|||
} |
|||
} |
|||
@ -0,0 +1,106 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { Component, Inject } from '@angular/core'; |
|||
import { PageComponent } from '@shared/components/page.component'; |
|||
import { Store } from '@ngrx/store'; |
|||
import { AppState } from '@core/core.state'; |
|||
import { WINDOW } from '@core/services/window.service'; |
|||
import { BreakpointObserver } from '@angular/cdk/layout'; |
|||
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; |
|||
import { MenuService } from '@core/services/menu.service'; |
|||
import { distinctUntilChanged, filter, map, mergeMap, take } from 'rxjs/operators'; |
|||
import { merge } from 'rxjs'; |
|||
import { MenuSection } from '@core/services/menu.models'; |
|||
import { ActiveComponentService } from '@core/services/active-component.service'; |
|||
|
|||
@Component({ |
|||
selector: 'tb-router-tabs', |
|||
templateUrl: './router-tabs.component.html', |
|||
styleUrls: ['./router-tabs.component.scss'] |
|||
}) |
|||
export class RouterTabsComponent extends PageComponent { |
|||
|
|||
hideCurrentTabs = false; |
|||
|
|||
tabs$ = merge(this.menuService.menuSections(), |
|||
this.router.events.pipe( |
|||
filter((event) => event instanceof NavigationEnd ), |
|||
distinctUntilChanged() |
|||
) |
|||
).pipe( |
|||
mergeMap(() => this.menuService.menuSections().pipe(take(1))), |
|||
map((sections) => this.buildTabs(this.activatedRoute, sections)) |
|||
); |
|||
|
|||
constructor(protected store: Store<AppState>, |
|||
private activatedRoute: ActivatedRoute, |
|||
public router: Router, |
|||
private menuService: MenuService, |
|||
private activeComponentService: ActiveComponentService, |
|||
@Inject(WINDOW) private window: Window, |
|||
public breakpointObserver: BreakpointObserver) { |
|||
super(store); |
|||
} |
|||
|
|||
activeComponentChanged(activeComponent: any) { |
|||
this.activeComponentService.setCurrentActiveComponent(activeComponent); |
|||
let snapshot = this.router.routerState.snapshot.root; |
|||
this.hideCurrentTabs = false; |
|||
let found = false; |
|||
while (snapshot.children.length) { |
|||
if (snapshot.component && snapshot.component === RouterTabsComponent) { |
|||
if (this.activatedRoute.snapshot === snapshot) { |
|||
found = true; |
|||
} else if (found) { |
|||
this.hideCurrentTabs = true; |
|||
break; |
|||
} |
|||
} |
|||
snapshot = snapshot.children[0]; |
|||
} |
|||
} |
|||
|
|||
private buildTabs(activatedRoute: ActivatedRoute, sections: MenuSection[]): Array<MenuSection> { |
|||
const sectionPath = '/' + activatedRoute.pathFromRoot.map(r => r.snapshot.url) |
|||
.filter(f => !!f[0]).map(f => f.map(f1 => f1.path).join('/')).join('/'); |
|||
const found = this.findRootSection(sections, sectionPath); |
|||
if (found) { |
|||
const rootPath = sectionPath.substring(0, sectionPath.length - found.path.length); |
|||
const isRoot = rootPath === ''; |
|||
const tabs: Array<MenuSection> = found ? found.pages.filter(page => !page.disabled && (!page.rootOnly || isRoot)) : []; |
|||
return tabs.map((tab) => ({...tab, path: rootPath + tab.path})); |
|||
} else { |
|||
return []; |
|||
} |
|||
} |
|||
|
|||
private findRootSection(sections: MenuSection[], sectionPath: string): MenuSection { |
|||
for (const section of sections) { |
|||
if (sectionPath.endsWith(section.path)) { |
|||
return section; |
|||
} |
|||
if (section.pages?.length) { |
|||
const found = this.findRootSection(section.pages, sectionPath); |
|||
if (found) { |
|||
return found; |
|||
} |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,58 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { Injectable, NgModule } from '@angular/core'; |
|||
import { Resolve, RouterModule, Routes } from '@angular/router'; |
|||
import { Authority } from '@shared/models/authority.enum'; |
|||
import { Observable } from 'rxjs'; |
|||
import { OAuth2Service } from '@core/http/oauth2.service'; |
|||
import { AlarmTableComponent } from '@home/components/alarm/alarm-table.component'; |
|||
import { AlarmsMode } from '@shared/models/alarm.models'; |
|||
|
|||
@Injectable() |
|||
export class OAuth2LoginProcessingUrlResolver implements Resolve<string> { |
|||
|
|||
constructor(private oauth2Service: OAuth2Service) { |
|||
} |
|||
|
|||
resolve(): Observable<string> { |
|||
return this.oauth2Service.getLoginProcessingUrl(); |
|||
} |
|||
} |
|||
|
|||
const routes: Routes = [ |
|||
{ |
|||
path: 'alarms', |
|||
component: AlarmTableComponent, |
|||
data: { |
|||
auth: [Authority.TENANT_ADMIN, Authority.CUSTOMER_USER], |
|||
title: 'alarm.alarms', |
|||
breadcrumb: { |
|||
label: 'alarm.alarms', |
|||
icon: 'notifications' |
|||
}, |
|||
isPage: true, |
|||
alarmsMode: AlarmsMode.ALL |
|||
} |
|||
} |
|||
]; |
|||
|
|||
@NgModule({ |
|||
imports: [RouterModule.forChild(routes)], |
|||
exports: [RouterModule], |
|||
providers: [] |
|||
}) |
|||
export class AlarmRoutingModule { } |
|||
@ -0,0 +1,34 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { NgModule } from '@angular/core'; |
|||
import { CommonModule } from '@angular/common'; |
|||
import { SharedModule } from '@shared/shared.module'; |
|||
import { HomeDialogsModule } from '../../dialogs/home-dialogs.module'; |
|||
import { HomeComponentsModule } from '@modules/home/components/home-components.module'; |
|||
import { AlarmRoutingModule } from '@home/pages/alarm/alarm-routing.module'; |
|||
|
|||
@NgModule({ |
|||
declarations: [], |
|||
imports: [ |
|||
CommonModule, |
|||
SharedModule, |
|||
HomeComponentsModule, |
|||
HomeDialogsModule, |
|||
AlarmRoutingModule |
|||
] |
|||
}) |
|||
export class AlarmModule { } |
|||
@ -0,0 +1,53 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { RouterModule, Routes } from '@angular/router'; |
|||
import { Authority } from '@shared/models/authority.enum'; |
|||
import { NgModule } from '@angular/core'; |
|||
import { deviceRoutes } from '@home/pages/device/device-routing.module'; |
|||
import { assetRoutes } from '@home/pages/asset/asset-routing.module'; |
|||
import { entityViewRoutes } from '@home/pages/entity-view/entity-view-routing.module'; |
|||
|
|||
const routes: Routes = [ |
|||
{ |
|||
path: 'entities', |
|||
data: { |
|||
auth: [Authority.TENANT_ADMIN, Authority.CUSTOMER_USER], |
|||
breadcrumb: { |
|||
skip: true |
|||
} |
|||
}, |
|||
children: [ |
|||
{ |
|||
path: '', |
|||
children: [], |
|||
data: { |
|||
auth: [Authority.TENANT_ADMIN, Authority.CUSTOMER_USER], |
|||
redirectTo: '/entities/devices' |
|||
} |
|||
}, |
|||
...deviceRoutes, |
|||
...assetRoutes, |
|||
...entityViewRoutes |
|||
] |
|||
} |
|||
]; |
|||
|
|||
@NgModule({ |
|||
imports: [RouterModule.forChild(routes)], |
|||
exports: [RouterModule] |
|||
}) |
|||
export class EntitiesRoutingModule { } |
|||
@ -0,0 +1,30 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { NgModule } from '@angular/core'; |
|||
import { CommonModule } from '@angular/common'; |
|||
import { SharedModule } from '@shared/shared.module'; |
|||
import { EntitiesRoutingModule } from '@home/pages/entities/entities-routing.module'; |
|||
|
|||
@NgModule({ |
|||
declarations: [], |
|||
imports: [ |
|||
CommonModule, |
|||
SharedModule, |
|||
EntitiesRoutingModule |
|||
] |
|||
}) |
|||
export class EntitiesModule { } |
|||
@ -0,0 +1,54 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { RouterModule, Routes } from '@angular/router'; |
|||
import { Authority } from '@shared/models/authority.enum'; |
|||
import { NgModule } from '@angular/core'; |
|||
import { ruleChainsRoutes } from '@home/pages/rulechain/rulechain-routing.module'; |
|||
import { otaUpdatesRoutes } from '@home/pages/ota-update/ota-update-routing.module'; |
|||
import { vcRoutes } from '@home/pages/vc/vc-routing.module'; |
|||
|
|||
const routes: Routes = [ |
|||
{ |
|||
path: 'features', |
|||
data: { |
|||
auth: [Authority.TENANT_ADMIN], |
|||
breadcrumb: { |
|||
label: 'feature.advanced-features', |
|||
icon: 'construction' |
|||
} |
|||
}, |
|||
children: [ |
|||
{ |
|||
path: '', |
|||
children: [], |
|||
data: { |
|||
auth: [Authority.TENANT_ADMIN], |
|||
redirectTo: '/features/ruleChains' |
|||
} |
|||
}, |
|||
...ruleChainsRoutes, |
|||
...otaUpdatesRoutes, |
|||
...vcRoutes |
|||
] |
|||
} |
|||
]; |
|||
|
|||
@NgModule({ |
|||
imports: [RouterModule.forChild(routes)], |
|||
exports: [RouterModule] |
|||
}) |
|||
export class FeaturesRoutingModule { } |
|||
@ -0,0 +1,30 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { NgModule } from '@angular/core'; |
|||
import { CommonModule } from '@angular/common'; |
|||
import { SharedModule } from '@shared/shared.module'; |
|||
import { FeaturesRoutingModule } from '@home/pages/features/features-routing.module'; |
|||
|
|||
@NgModule({ |
|||
declarations: [], |
|||
imports: [ |
|||
CommonModule, |
|||
SharedModule, |
|||
FeaturesRoutingModule |
|||
] |
|||
}) |
|||
export class FeaturesModule { } |
|||
@ -0,0 +1,135 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { ActivatedRoute, RouterModule, Routes } from '@angular/router'; |
|||
import { Authority } from '@shared/models/authority.enum'; |
|||
import { Component, NgModule, OnInit } from '@angular/core'; |
|||
import { RouterTabsComponent } from '@home/components/router-tabs.component'; |
|||
import { isDefinedAndNotNull } from '@core/utils'; |
|||
|
|||
@Component({ |
|||
selector: 'tb-notification-temp-component', |
|||
template: '<div>{{text}}</div>', |
|||
styleUrls: [] |
|||
}) |
|||
class NotificationTempComponent implements OnInit { |
|||
|
|||
text: string; |
|||
|
|||
constructor(private route: ActivatedRoute) {} |
|||
|
|||
ngOnInit() { |
|||
if (isDefinedAndNotNull(this.route.snapshot.data.text)) { |
|||
this.text = this.route.snapshot.data.text; |
|||
} |
|||
} |
|||
} |
|||
|
|||
const routes: Routes = [ |
|||
{ |
|||
path: 'notification', |
|||
component: RouterTabsComponent, |
|||
data: { |
|||
auth: [Authority.TENANT_ADMIN, Authority.CUSTOMER_USER], |
|||
breadcrumb: { |
|||
label: 'notification.notification-center', |
|||
icon: 'mdi:message-badge' |
|||
} |
|||
}, |
|||
children: [ |
|||
{ |
|||
path: '', |
|||
children: [], |
|||
data: { |
|||
auth: [Authority.TENANT_ADMIN, Authority.CUSTOMER_USER], |
|||
redirectTo: '/notification/inbox' |
|||
} |
|||
}, |
|||
{ |
|||
path: 'inbox', |
|||
component: NotificationTempComponent, |
|||
data: { |
|||
auth: [Authority.TENANT_ADMIN, Authority.CUSTOMER_USER], |
|||
title: 'notification.inbox', |
|||
breadcrumb: { |
|||
label: 'notification.inbox', |
|||
icon: 'inbox' |
|||
}, |
|||
text: 'TODO: Implement inbox' |
|||
} |
|||
}, |
|||
{ |
|||
path: 'sent', |
|||
component: NotificationTempComponent, |
|||
data: { |
|||
auth: [Authority.TENANT_ADMIN], |
|||
title: 'notification.sent', |
|||
breadcrumb: { |
|||
label: 'notification.sent', |
|||
icon: 'outbox' |
|||
}, |
|||
text: 'TODO: Implement sent' |
|||
} |
|||
}, |
|||
{ |
|||
path: 'templates', |
|||
component: NotificationTempComponent, |
|||
data: { |
|||
auth: [Authority.TENANT_ADMIN], |
|||
title: 'notification.templates', |
|||
breadcrumb: { |
|||
label: 'notification.templates', |
|||
icon: 'mdi:message-draw' |
|||
}, |
|||
text: 'TODO: Implement templates' |
|||
} |
|||
}, |
|||
{ |
|||
path: 'recipients', |
|||
component: NotificationTempComponent, |
|||
data: { |
|||
auth: [Authority.TENANT_ADMIN], |
|||
title: 'notification.recipients', |
|||
breadcrumb: { |
|||
label: 'notification.recipients', |
|||
icon: 'contacts' |
|||
}, |
|||
text: 'TODO: Implement recipients' |
|||
} |
|||
}, |
|||
{ |
|||
path: 'rules', |
|||
component: NotificationTempComponent, |
|||
data: { |
|||
auth: [Authority.TENANT_ADMIN], |
|||
title: 'notification.rules', |
|||
breadcrumb: { |
|||
label: 'notification.rules', |
|||
icon: 'mdi:message-cog' |
|||
}, |
|||
text: 'TODO: Implement rules' |
|||
} |
|||
} |
|||
] |
|||
} |
|||
]; |
|||
|
|||
@NgModule({ |
|||
declarations: [NotificationTempComponent], |
|||
imports: [RouterModule.forChild(routes)], |
|||
exports: [RouterModule] |
|||
}) |
|||
export class NotificationRoutingModule { } |
|||
@ -0,0 +1,30 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { NgModule } from '@angular/core'; |
|||
import { CommonModule } from '@angular/common'; |
|||
import { SharedModule } from '@shared/shared.module'; |
|||
import { NotificationRoutingModule } from '@home/pages/notification/notification-routing.module'; |
|||
|
|||
@NgModule({ |
|||
declarations: [], |
|||
imports: [ |
|||
CommonModule, |
|||
SharedModule, |
|||
NotificationRoutingModule |
|||
] |
|||
}) |
|||
export class NotificationModule { } |
|||
@ -0,0 +1,23 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
export interface UserSettings { |
|||
openedMenuSections?: string[]; |
|||
} |
|||
|
|||
export const initialUserSettings: UserSettings = { |
|||
openedMenuSections: [] |
|||
}; |
|||
|
Before Width: | Height: | Size: 2.3 MiB |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue