UI: Move send notification button router tabs panel.
This commit is contained in:
parent
5f3e277ca1
commit
97278c9ef2
@ -178,6 +178,7 @@ import { modulesMap } from '@modules/common/modules-map';
|
|||||||
import { SlackConversationAutocompleteComponent } from '@home/components/notification/slack-conversation-autocomplete.component';
|
import { SlackConversationAutocompleteComponent } from '@home/components/notification/slack-conversation-autocomplete.component';
|
||||||
import { AlarmAssigneePanelComponent } from '@home/components/alarm/alarm-assignee-panel.component';
|
import { AlarmAssigneePanelComponent } from '@home/components/alarm/alarm-assignee-panel.component';
|
||||||
import { RouterTabsComponent } from '@home/components/router-tabs.component';
|
import { RouterTabsComponent } from '@home/components/router-tabs.component';
|
||||||
|
import { SendNotificationButtonComponent } from '@home/components/notification/send-notification-button.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations:
|
declarations:
|
||||||
@ -324,7 +325,8 @@ import { RouterTabsComponent } from '@home/components/router-tabs.component';
|
|||||||
RateLimitsComponent,
|
RateLimitsComponent,
|
||||||
RateLimitsTextComponent,
|
RateLimitsTextComponent,
|
||||||
RateLimitsDetailsDialogComponent,
|
RateLimitsDetailsDialogComponent,
|
||||||
SlackConversationAutocompleteComponent
|
SlackConversationAutocompleteComponent,
|
||||||
|
SendNotificationButtonComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
@ -464,7 +466,8 @@ import { RouterTabsComponent } from '@home/components/router-tabs.component';
|
|||||||
RateLimitsComponent,
|
RateLimitsComponent,
|
||||||
RateLimitsTextComponent,
|
RateLimitsTextComponent,
|
||||||
RateLimitsDetailsDialogComponent,
|
RateLimitsDetailsDialogComponent,
|
||||||
SlackConversationAutocompleteComponent
|
SlackConversationAutocompleteComponent,
|
||||||
|
SendNotificationButtonComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
WidgetComponentService,
|
WidgetComponentService,
|
||||||
|
|||||||
@ -15,10 +15,12 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<div fxFlex="100" fxLayout="row" fxLayoutAlign="end center">
|
<div *ngIf="show()" fxLayout="row" fxLayoutAlign="end end" style="height: 100%; padding: 0 16px;">
|
||||||
<button mat-flat-button color="primary" (click)="sendNotification($event)">
|
<button fxHide.lt-md mat-flat-button color="primary" (click)="sendNotification($event)">
|
||||||
<div fxLayout="row" fxLayoutAlign="start center">
|
<mat-icon>send</mat-icon>
|
||||||
<mat-icon>send</mat-icon>{{ 'notification.send-notification' | translate }}
|
<span translate>notification.send-notification</span>
|
||||||
</div>
|
</button>
|
||||||
|
<button class="mat-elevation-z0" fxHide.gt-sm mat-mini-fab color="primary" (click)="sendNotification($event)">
|
||||||
|
<mat-icon>send</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
///
|
||||||
|
/// 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 } from '@angular/core';
|
||||||
|
import {
|
||||||
|
RequestNotificationDialogData,
|
||||||
|
SentNotificationDialogComponent
|
||||||
|
} from '@home/pages/notification/sent/sent-notification-dialog.componet';
|
||||||
|
import { NotificationTemplate } from '@shared/models/notification.models';
|
||||||
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { ActiveComponentService } from '@core/services/active-component.service';
|
||||||
|
import { EntitiesTableComponent } from '@home/components/entity/entities-table.component';
|
||||||
|
import { EntityType } from '@shared/models/entity-type.models';
|
||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
import { AppState } from '@core/core.state';
|
||||||
|
import { getCurrentAuthUser } from '@core/auth/auth.selectors';
|
||||||
|
import { Authority } from '@shared/models/authority.enum';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'tb-send-notification-button',
|
||||||
|
templateUrl: './send-notification-button.component.html',
|
||||||
|
})
|
||||||
|
export class SendNotificationButtonComponent {
|
||||||
|
|
||||||
|
authUser = getCurrentAuthUser(this.store);
|
||||||
|
|
||||||
|
constructor(private dialog: MatDialog,
|
||||||
|
private store: Store<AppState>,
|
||||||
|
private activeComponentService: ActiveComponentService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
sendNotification($event: Event) {
|
||||||
|
if ($event) {
|
||||||
|
$event.stopPropagation();
|
||||||
|
}
|
||||||
|
this.dialog.open<SentNotificationDialogComponent, RequestNotificationDialogData,
|
||||||
|
NotificationTemplate>(SentNotificationDialogComponent, {
|
||||||
|
disableClose: true,
|
||||||
|
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
|
||||||
|
data: {
|
||||||
|
isAdd: true
|
||||||
|
}
|
||||||
|
}).afterClosed().subscribe((res) => {
|
||||||
|
if (res) {
|
||||||
|
const comp = this.activeComponentService.getCurrentActiveComponent();
|
||||||
|
if (comp instanceof EntitiesTableComponent) {
|
||||||
|
const entitiesTableComponent = comp as EntitiesTableComponent;
|
||||||
|
if (entitiesTableComponent.entitiesTableConfig.entityType === EntityType.NOTIFICATION_REQUEST) {
|
||||||
|
entitiesTableComponent.entitiesTableConfig.updateData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public show(): boolean {
|
||||||
|
return this.authUser.authority !== Authority.CUSTOMER_USER;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
-->
|
-->
|
||||||
<div fxFlex fxLayout="column" style="width: 100%;">
|
<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">
|
<div fxLayout="row" style="width: 100%;">
|
||||||
|
<nav fxFlex *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"
|
<a *ngFor="let tab of tabs$ | async"
|
||||||
routerLink="{{tab.path}}"
|
routerLink="{{tab.path}}"
|
||||||
routerLinkActive
|
routerLinkActive
|
||||||
@ -28,6 +29,8 @@
|
|||||||
<span>{{tab.name | translate}}</span>
|
<span>{{tab.name | translate}}</span>
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<tb-anchor #tabsHeaderComponent></tb-anchor>
|
||||||
|
</div>
|
||||||
<mat-tab-nav-panel #tabPanel fxFlex fxLayout="column" class="tb-router-tabs-content">
|
<mat-tab-nav-panel #tabPanel fxFlex fxLayout="column" class="tb-router-tabs-content">
|
||||||
<router-outlet #routerOutlet="outlet" (activate)="activeComponentChanged($event)"></router-outlet>
|
<router-outlet #routerOutlet="outlet" (activate)="activeComponentChanged($event)"></router-outlet>
|
||||||
</mat-tab-nav-panel>
|
</mat-tab-nav-panel>
|
||||||
|
|||||||
@ -14,33 +14,35 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import { Component, Inject } from '@angular/core';
|
import { Component, ComponentRef, OnInit, Type, ViewChild } from '@angular/core';
|
||||||
import { PageComponent } from '@shared/components/page.component';
|
import { PageComponent } from '@shared/components/page.component';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { AppState } from '@core/core.state';
|
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 { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
|
||||||
import { MenuService } from '@core/services/menu.service';
|
import { MenuService } from '@core/services/menu.service';
|
||||||
import { distinctUntilChanged, filter, map, mergeMap, take } from 'rxjs/operators';
|
import { distinctUntilChanged, filter, map, mergeMap, take } from 'rxjs/operators';
|
||||||
import { merge } from 'rxjs';
|
import { merge } from 'rxjs';
|
||||||
import { MenuSection } from '@core/services/menu.models';
|
import { MenuSection } from '@core/services/menu.models';
|
||||||
import { ActiveComponentService } from '@core/services/active-component.service';
|
import { ActiveComponentService } from '@core/services/active-component.service';
|
||||||
|
import { TbAnchorComponent } from '@shared/components/tb-anchor.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-router-tabs',
|
selector: 'tb-router-tabs',
|
||||||
templateUrl: './router-tabs.component.html',
|
templateUrl: './router-tabs.component.html',
|
||||||
styleUrls: ['./router-tabs.component.scss']
|
styleUrls: ['./router-tabs.component.scss']
|
||||||
})
|
})
|
||||||
export class RouterTabsComponent extends PageComponent {
|
export class RouterTabsComponent extends PageComponent implements OnInit {
|
||||||
|
|
||||||
|
@ViewChild('tabsHeaderComponent', {static: true}) tabsHeaderComponentAnchor: TbAnchorComponent;
|
||||||
|
|
||||||
|
tabsHeaderComponentRef: ComponentRef<any>;
|
||||||
|
|
||||||
hideCurrentTabs = false;
|
hideCurrentTabs = false;
|
||||||
|
|
||||||
tabs$ = merge(this.menuService.menuSections(),
|
tabs$ = merge(this.menuService.menuSections(),
|
||||||
this.router.events.pipe(
|
this.router.events.pipe(
|
||||||
filter((event) => event instanceof NavigationEnd ),
|
filter((event) => event instanceof NavigationEnd ),
|
||||||
distinctUntilChanged()
|
distinctUntilChanged())
|
||||||
)
|
|
||||||
).pipe(
|
).pipe(
|
||||||
mergeMap(() => this.menuService.menuSections().pipe(take(1))),
|
mergeMap(() => this.menuService.menuSections().pipe(take(1))),
|
||||||
map((sections) => this.buildTabs(this.activatedRoute, sections))
|
map((sections) => this.buildTabs(this.activatedRoute, sections))
|
||||||
@ -50,12 +52,16 @@ export class RouterTabsComponent extends PageComponent {
|
|||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
public router: Router,
|
public router: Router,
|
||||||
private menuService: MenuService,
|
private menuService: MenuService,
|
||||||
private activeComponentService: ActiveComponentService,
|
private activeComponentService: ActiveComponentService) {
|
||||||
@Inject(WINDOW) private window: Window,
|
|
||||||
public breakpointObserver: BreakpointObserver) {
|
|
||||||
super(store);
|
super(store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.activatedRoute.data.subscribe(
|
||||||
|
(data) => this.buildTabsHeaderComponent(data)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
activeComponentChanged(activeComponent: any) {
|
activeComponentChanged(activeComponent: any) {
|
||||||
this.activeComponentService.setCurrentActiveComponent(activeComponent);
|
this.activeComponentService.setCurrentActiveComponent(activeComponent);
|
||||||
let snapshot = this.router.routerState.snapshot.root;
|
let snapshot = this.router.routerState.snapshot.root;
|
||||||
@ -103,4 +109,17 @@ export class RouterTabsComponent extends PageComponent {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private buildTabsHeaderComponent(snapshotData: any) {
|
||||||
|
const viewContainerRef = this.tabsHeaderComponentAnchor.viewContainerRef;
|
||||||
|
if (this.tabsHeaderComponentRef) {
|
||||||
|
this.tabsHeaderComponentRef.destroy();
|
||||||
|
this.tabsHeaderComponentRef = null;
|
||||||
|
viewContainerRef.clear();
|
||||||
|
}
|
||||||
|
const tabsHeaderComponentType: Type<any> = snapshotData.routerTabsHeaderComponent;
|
||||||
|
if (tabsHeaderComponentType) {
|
||||||
|
this.tabsHeaderComponentRef = viewContainerRef.createComponent(tabsHeaderComponentType, {index: 0});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import { SentTableConfigResolver } from '@home/pages/notification/sent/sent-tabl
|
|||||||
import { RecipientTableConfigResolver } from '@home/pages/notification/recipient/recipient-table-config.resolver';
|
import { RecipientTableConfigResolver } from '@home/pages/notification/recipient/recipient-table-config.resolver';
|
||||||
import { TemplateTableConfigResolver } from '@home/pages/notification/template/template-table-config.resolver';
|
import { TemplateTableConfigResolver } from '@home/pages/notification/template/template-table-config.resolver';
|
||||||
import { RuleTableConfigResolver } from '@home/pages/notification/rule/rule-table-config.resolver';
|
import { RuleTableConfigResolver } from '@home/pages/notification/rule/rule-table-config.resolver';
|
||||||
|
import { SendNotificationButtonComponent } from '@home/components/notification/send-notification-button.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
@ -34,7 +35,8 @@ const routes: Routes = [
|
|||||||
breadcrumb: {
|
breadcrumb: {
|
||||||
label: 'notification.notification-center',
|
label: 'notification.notification-center',
|
||||||
icon: 'mdi:message-badge'
|
icon: 'mdi:message-badge'
|
||||||
}
|
},
|
||||||
|
routerTabsHeaderComponent: SendNotificationButtonComponent
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -36,7 +36,6 @@ import { EscalationFormComponent } from '@home/pages/notification/rule/escalatio
|
|||||||
import { EscalationsComponent } from '@home/pages/notification/rule/escalations.component';
|
import { EscalationsComponent } from '@home/pages/notification/rule/escalations.component';
|
||||||
import { RuleNotificationDialogComponent } from '@home/pages/notification/rule/rule-notification-dialog.component';
|
import { RuleNotificationDialogComponent } from '@home/pages/notification/rule/rule-notification-dialog.component';
|
||||||
import { RuleTableHeaderComponent } from '@home/pages/notification/rule/rule-table-header.component';
|
import { RuleTableHeaderComponent } from '@home/pages/notification/rule/rule-table-header.component';
|
||||||
import { SentTableHeaderComponent } from '@home/pages/notification/sent/sent-table-header.component';
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -52,8 +51,7 @@ import { SentTableHeaderComponent } from '@home/pages/notification/sent/sent-tab
|
|||||||
EscalationFormComponent,
|
EscalationFormComponent,
|
||||||
EscalationsComponent,
|
EscalationsComponent,
|
||||||
RuleNotificationDialogComponent,
|
RuleNotificationDialogComponent,
|
||||||
RuleTableHeaderComponent,
|
RuleTableHeaderComponent
|
||||||
SentTableHeaderComponent
|
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
|||||||
@ -47,7 +47,6 @@ import {
|
|||||||
} from '@home/pages/notification/sent/sent-error-dialog.component';
|
} from '@home/pages/notification/sent/sent-error-dialog.component';
|
||||||
import { ActivatedRouteSnapshot, Resolve } from '@angular/router';
|
import { ActivatedRouteSnapshot, Resolve } from '@angular/router';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { SentTableHeaderComponent } from '@home/pages/notification/sent/sent-table-header.component';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SentTableConfigResolver implements Resolve<EntityTableConfig<NotificationRequest, PageLink, NotificationRequestInfo>> {
|
export class SentTableConfigResolver implements Resolve<EntityTableConfig<NotificationRequest, PageLink, NotificationRequestInfo>> {
|
||||||
@ -77,7 +76,6 @@ export class SentTableConfigResolver implements Resolve<EntityTableConfig<Notifi
|
|||||||
|
|
||||||
this.config.cellActionDescriptors = this.configureCellActions();
|
this.config.cellActionDescriptors = this.configureCellActions();
|
||||||
|
|
||||||
this.config.headerComponent = SentTableHeaderComponent;
|
|
||||||
this.config.onEntityAction = action => this.onRequestAction(action);
|
this.config.onEntityAction = action => this.onRequestAction(action);
|
||||||
|
|
||||||
this.config.handleRowClick = (event, entity) => {
|
this.config.handleRowClick = (event, entity) => {
|
||||||
|
|||||||
@ -1,18 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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{
|
|
||||||
width: 10000px;
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
///
|
|
||||||
/// 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 } from '@angular/core';
|
|
||||||
import { EntityTableHeaderComponent } from '@home/components/entity/entity-table-header.component';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
import { AppState } from '@core/core.state';
|
|
||||||
import { NotificationRequest, NotificationRequestInfo } from '@shared/models/notification.models';
|
|
||||||
import { PageLink } from '@shared/models/page/page-link';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'tb-sent-table-header',
|
|
||||||
templateUrl: './sent-table-header.component.html',
|
|
||||||
styleUrls: ['sent-table-header.component.scss']
|
|
||||||
})
|
|
||||||
export class SentTableHeaderComponent extends EntityTableHeaderComponent<NotificationRequest, PageLink, NotificationRequestInfo> {
|
|
||||||
|
|
||||||
constructor(protected store: Store<AppState>) {
|
|
||||||
super(store);
|
|
||||||
}
|
|
||||||
|
|
||||||
sendNotification($event: Event) {
|
|
||||||
this.entitiesTableConfig.onEntityAction({event: $event, action: 'add', entity: null});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user