diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts index a62363c7ff..e1028b321a 100644 --- a/ui-ngx/src/app/modules/home/components/home-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts @@ -178,6 +178,7 @@ import { modulesMap } from '@modules/common/modules-map'; import { SlackConversationAutocompleteComponent } from '@home/components/notification/slack-conversation-autocomplete.component'; import { AlarmAssigneePanelComponent } from '@home/components/alarm/alarm-assignee-panel.component'; import { RouterTabsComponent } from '@home/components/router-tabs.component'; +import { SendNotificationButtonComponent } from '@home/components/notification/send-notification-button.component'; @NgModule({ declarations: @@ -324,7 +325,8 @@ import { RouterTabsComponent } from '@home/components/router-tabs.component'; RateLimitsComponent, RateLimitsTextComponent, RateLimitsDetailsDialogComponent, - SlackConversationAutocompleteComponent + SlackConversationAutocompleteComponent, + SendNotificationButtonComponent ], imports: [ CommonModule, @@ -464,7 +466,8 @@ import { RouterTabsComponent } from '@home/components/router-tabs.component'; RateLimitsComponent, RateLimitsTextComponent, RateLimitsDetailsDialogComponent, - SlackConversationAutocompleteComponent + SlackConversationAutocompleteComponent, + SendNotificationButtonComponent ], providers: [ WidgetComponentService, diff --git a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.html b/ui-ngx/src/app/modules/home/components/notification/send-notification-button.component.html similarity index 59% rename from ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.html rename to ui-ngx/src/app/modules/home/components/notification/send-notification-button.component.html index 45738d09fe..60f069c28e 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.html +++ b/ui-ngx/src/app/modules/home/components/notification/send-notification-button.component.html @@ -15,10 +15,12 @@ limitations under the License. --> -
- +
diff --git a/ui-ngx/src/app/modules/home/components/notification/send-notification-button.component.ts b/ui-ngx/src/app/modules/home/components/notification/send-notification-button.component.ts new file mode 100644 index 0000000000..2842e220f9 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/notification/send-notification-button.component.ts @@ -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, + private activeComponentService: ActiveComponentService) { + } + + sendNotification($event: Event) { + if ($event) { + $event.stopPropagation(); + } + this.dialog.open(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; + } + +} diff --git a/ui-ngx/src/app/modules/home/components/router-tabs.component.html b/ui-ngx/src/app/modules/home/components/router-tabs.component.html index 5dba3ea8e1..afcc4d9fa9 100644 --- a/ui-ngx/src/app/modules/home/components/router-tabs.component.html +++ b/ui-ngx/src/app/modules/home/components/router-tabs.component.html @@ -16,18 +16,21 @@ -->
- +
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/router-tabs.component.ts b/ui-ngx/src/app/modules/home/components/router-tabs.component.ts index aa44238389..65c0074227 100644 --- a/ui-ngx/src/app/modules/home/components/router-tabs.component.ts +++ b/ui-ngx/src/app/modules/home/components/router-tabs.component.ts @@ -14,33 +14,35 @@ /// 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 { 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'; +import { TbAnchorComponent } from '@shared/components/tb-anchor.component'; @Component({ selector: 'tb-router-tabs', templateUrl: './router-tabs.component.html', 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; hideCurrentTabs = false; tabs$ = merge(this.menuService.menuSections(), this.router.events.pipe( filter((event) => event instanceof NavigationEnd ), - distinctUntilChanged() - ) + distinctUntilChanged()) ).pipe( mergeMap(() => this.menuService.menuSections().pipe(take(1))), map((sections) => this.buildTabs(this.activatedRoute, sections)) @@ -50,12 +52,16 @@ export class RouterTabsComponent extends PageComponent { private activatedRoute: ActivatedRoute, public router: Router, private menuService: MenuService, - private activeComponentService: ActiveComponentService, - @Inject(WINDOW) private window: Window, - public breakpointObserver: BreakpointObserver) { + private activeComponentService: ActiveComponentService) { super(store); } + ngOnInit() { + this.activatedRoute.data.subscribe( + (data) => this.buildTabsHeaderComponent(data) + ); + } + activeComponentChanged(activeComponent: any) { this.activeComponentService.setCurrentActiveComponent(activeComponent); let snapshot = this.router.routerState.snapshot.root; @@ -103,4 +109,17 @@ export class RouterTabsComponent extends PageComponent { 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 = snapshotData.routerTabsHeaderComponent; + if (tabsHeaderComponentType) { + this.tabsHeaderComponentRef = viewContainerRef.createComponent(tabsHeaderComponentType, {index: 0}); + } + } + } diff --git a/ui-ngx/src/app/modules/home/pages/notification/notification-routing.module.ts b/ui-ngx/src/app/modules/home/pages/notification/notification-routing.module.ts index 791a1d97c4..480cf97f99 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/notification-routing.module.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/notification-routing.module.ts @@ -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 { TemplateTableConfigResolver } from '@home/pages/notification/template/template-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 = [ { @@ -34,7 +35,8 @@ const routes: Routes = [ breadcrumb: { label: 'notification.notification-center', icon: 'mdi:message-badge' - } + }, + routerTabsHeaderComponent: SendNotificationButtonComponent }, children: [ { diff --git a/ui-ngx/src/app/modules/home/pages/notification/notification.module.ts b/ui-ngx/src/app/modules/home/pages/notification/notification.module.ts index 48751e08ba..53fbb095dd 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/notification.module.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/notification.module.ts @@ -36,7 +36,6 @@ import { EscalationFormComponent } from '@home/pages/notification/rule/escalatio import { EscalationsComponent } from '@home/pages/notification/rule/escalations.component'; import { RuleNotificationDialogComponent } from '@home/pages/notification/rule/rule-notification-dialog.component'; import { RuleTableHeaderComponent } from '@home/pages/notification/rule/rule-table-header.component'; -import { SentTableHeaderComponent } from '@home/pages/notification/sent/sent-table-header.component'; @NgModule({ declarations: [ @@ -52,8 +51,7 @@ import { SentTableHeaderComponent } from '@home/pages/notification/sent/sent-tab EscalationFormComponent, EscalationsComponent, RuleNotificationDialogComponent, - RuleTableHeaderComponent, - SentTableHeaderComponent + RuleTableHeaderComponent ], imports: [ CommonModule, diff --git a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-config.resolver.ts b/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-config.resolver.ts index f25a037aeb..c28f4f9182 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-config.resolver.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-config.resolver.ts @@ -47,7 +47,6 @@ import { } from '@home/pages/notification/sent/sent-error-dialog.component'; import { ActivatedRouteSnapshot, Resolve } from '@angular/router'; import { Injectable } from '@angular/core'; -import { SentTableHeaderComponent } from '@home/pages/notification/sent/sent-table-header.component'; @Injectable() export class SentTableConfigResolver implements Resolve> { @@ -77,7 +76,6 @@ export class SentTableConfigResolver implements Resolve this.onRequestAction(action); this.config.handleRowClick = (event, entity) => { diff --git a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.scss b/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.scss deleted file mode 100644 index 33537b4b23..0000000000 --- a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.scss +++ /dev/null @@ -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; -} diff --git a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.ts b/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.ts deleted file mode 100644 index 7de3b536a5..0000000000 --- a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.ts +++ /dev/null @@ -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 { - - constructor(protected store: Store) { - super(store); - } - - sendNotification($event: Event) { - this.entitiesTableConfig.onEntityAction({event: $event, action: 'add', entity: null}); - } - -}