Browse Source

UI: Minor change in notification

pull/7911/head
Vladyslav_Prykhodko 3 years ago
parent
commit
fa1a5f086f
  1. 2
      dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java
  2. 24
      ui-ngx/src/app/core/services/menu.service.ts
  3. 1
      ui-ngx/src/app/modules/home/pages/admin/admin-routing.module.ts
  4. 4
      ui-ngx/src/app/modules/home/pages/admin/admin.module.ts
  5. 49
      ui-ngx/src/app/modules/home/pages/admin/notification-settings.component.html
  6. 86
      ui-ngx/src/app/modules/home/pages/admin/notification-settings.component.ts
  7. 30
      ui-ngx/src/app/modules/home/pages/admin/sms-provider.component.html
  8. 64
      ui-ngx/src/app/modules/home/pages/admin/sms-provider.component.ts
  9. 4
      ui-ngx/src/app/modules/home/pages/notification/notification.module.ts
  10. 8
      ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-table-config.resolver.ts
  11. 8
      ui-ngx/src/app/modules/home/pages/notification/rule/rule-table-config.resolver.ts
  12. 2
      ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-config.resolver.ts
  13. 24
      ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.html
  14. 18
      ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.scss
  15. 39
      ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.ts
  16. 8
      ui-ngx/src/app/modules/home/pages/notification/template/template-table-config.resolver.ts
  17. 2
      ui-ngx/src/app/shared/components/notification/notification.component.scss
  18. 7
      ui-ngx/src/assets/locale/locale.constant-en_US.json

2
dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java

@ -186,7 +186,7 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS
NotificationTemplate ruleEngineComponentLifecycleFailureNotificationTemplate = createTemplate(tenantId, "Rule chain/node lifecycle failure notification", NotificationType.RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT, NotificationTemplate ruleEngineComponentLifecycleFailureNotificationTemplate = createTemplate(tenantId, "Rule chain/node lifecycle failure notification", NotificationType.RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT,
"${componentType} '${componentName}' failed to ${action}", "${componentType} '${componentName}' failed to ${action}",
"Rule chain '${ruleChainName}' - ${action} failure:<br/>${error}", "Rule chain '${ruleChainName}' - ${action} failure:<br/>${error}",
"warning", "Go to Rule chain", "/ruleChains/${ruleChainId}"); "warning", "Go to Rule chain", "/features/ruleChains/${ruleChainId}");
RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig ruleEngineComponentLifecycleEventRuleTriggerConfig = new RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig(); RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig ruleEngineComponentLifecycleEventRuleTriggerConfig = new RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig();
ruleEngineComponentLifecycleEventRuleTriggerConfig.setRuleChains(null); ruleEngineComponentLifecycleEventRuleTriggerConfig.setRuleChains(null);
ruleEngineComponentLifecycleEventRuleTriggerConfig.setRuleChainEvents(Set.of(ComponentLifecycleEvent.STARTED, ComponentLifecycleEvent.UPDATED, ComponentLifecycleEvent.STOPPED)); ruleEngineComponentLifecycleEventRuleTriggerConfig.setRuleChainEvents(Set.of(ComponentLifecycleEvent.STARTED, ComponentLifecycleEvent.UPDATED, ComponentLifecycleEvent.STOPPED));

24
ui-ngx/src/app/core/services/menu.service.ts

@ -212,13 +212,6 @@ export class MenuService {
icon: 'mdi:message-badge', icon: 'mdi:message-badge',
isMdiIcon: true isMdiIcon: true
}, },
{
id: guid(),
name: 'notification.notification',
type: 'link',
path: '/settings/notification',
icon: 'notifications'
},
{ {
id: guid(), id: guid(),
name: 'admin.queues', name: 'admin.queues',
@ -311,11 +304,6 @@ export class MenuService {
icon: 'sms', icon: 'sms',
path: '/settings/sms-provider' path: '/settings/sms-provider'
}, },
{
name: 'notification.notification',
icon: 'notifications',
path: '/settings/notification'
},
{ {
name: 'admin.security-settings', name: 'admin.security-settings',
icon: 'security', icon: 'security',
@ -585,13 +573,6 @@ export class MenuService {
path: '/settings/home', path: '/settings/home',
icon: 'settings_applications' icon: 'settings_applications'
}, },
{
id: guid(),
name: 'notification.notification',
type: 'link',
path: '/settings/notification',
icon: 'notifications'
},
{ {
id: guid(), id: guid(),
name: 'admin.repository', name: 'admin.repository',
@ -767,11 +748,6 @@ export class MenuService {
icon: 'settings_applications', icon: 'settings_applications',
path: '/settings/home' path: '/settings/home'
}, },
{
name: 'notification.notification',
icon: 'notifications',
path: '/settings/notification'
},
{ {
name: 'resource.resources-library', name: 'resource.resources-library',
icon: 'folder', icon: 'folder',

1
ui-ngx/src/app/modules/home/pages/admin/admin-routing.module.ts

@ -39,7 +39,6 @@ import { TwoFactorAuthSettingsComponent } from '@home/pages/admin/two-factor-aut
import { widgetsBundlesRoutes } from '@home/pages/widget/widget-library-routing.module'; import { widgetsBundlesRoutes } from '@home/pages/widget/widget-library-routing.module';
import { RouterTabsComponent } from '@home/components/router-tabs.component'; import { RouterTabsComponent } from '@home/components/router-tabs.component';
import { auditLogsRoutes } from '@home/pages/audit-log/audit-log-routing.module'; import { auditLogsRoutes } from '@home/pages/audit-log/audit-log-routing.module';
import { NotificationSettingsComponent } from '@home/pages/admin/notification-settings.component';
@Injectable() @Injectable()
export class OAuth2LoginProcessingUrlResolver implements Resolve<string> { export class OAuth2LoginProcessingUrlResolver implements Resolve<string> {

4
ui-ngx/src/app/modules/home/pages/admin/admin.module.ts

@ -32,7 +32,6 @@ import { QueueComponent } from '@home/pages/admin/queue/queue.component';
import { RepositoryAdminSettingsComponent } from '@home/pages/admin/repository-admin-settings.component'; import { RepositoryAdminSettingsComponent } from '@home/pages/admin/repository-admin-settings.component';
import { AutoCommitAdminSettingsComponent } from '@home/pages/admin/auto-commit-admin-settings.component'; import { AutoCommitAdminSettingsComponent } from '@home/pages/admin/auto-commit-admin-settings.component';
import { TwoFactorAuthSettingsComponent } from '@home/pages/admin/two-factor-auth-settings.component'; import { TwoFactorAuthSettingsComponent } from '@home/pages/admin/two-factor-auth-settings.component';
import { NotificationSettingsComponent } from '@home/pages/admin/notification-settings.component';
@NgModule({ @NgModule({
declarations: declarations:
@ -48,8 +47,7 @@ import { NotificationSettingsComponent } from '@home/pages/admin/notification-se
QueueComponent, QueueComponent,
RepositoryAdminSettingsComponent, RepositoryAdminSettingsComponent,
AutoCommitAdminSettingsComponent, AutoCommitAdminSettingsComponent,
TwoFactorAuthSettingsComponent, TwoFactorAuthSettingsComponent
NotificationSettingsComponent
], ],
imports: [ imports: [
CommonModule, CommonModule,

49
ui-ngx/src/app/modules/home/pages/admin/notification-settings.component.html

@ -1,49 +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.
-->
<div>
<mat-card appearance="outlined" class="settings-card">
<mat-card-header>
<mat-card-title>
<div fxLayout="row">
<span class="mat-headline-5" translate>admin.notification.notification-settings</span>
</div>
</mat-card-title>
</mat-card-header>
<mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async">
</mat-progress-bar>
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
<mat-card-content style="padding-top: 16px;">
<form [formGroup]="notificationSettingsForm" (ngSubmit)="save()">
<fieldset [disabled]="isLoading$ | async" formGroupName="deliveryMethodsConfigs">
<fieldset class="fields-group" formGroupName="SLACK">
<legend class="group-title" translate>admin.notification.slack</legend>
<mat-form-field class="mat-block">
<mat-label translate>admin.notification.slack-api-token</mat-label>
<input matInput formControlName="botToken" />
</mat-form-field>
</fieldset>
<div fxLayout="row" fxLayoutAlign="end center" class="layout-wrap">
<button mat-button mat-raised-button color="primary" [disabled]="(isLoading$ | async) || notificationSettingsForm.invalid || !notificationSettingsForm.dirty"
type="submit">{{'action.save' | translate}}
</button>
</div>
</fieldset>
</form>
</mat-card-content>
</mat-card>
</div>

86
ui-ngx/src/app/modules/home/pages/admin/notification-settings.component.ts

@ -1,86 +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, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { PageComponent } from '@shared/components/page.component';
import { FormBuilder, FormGroup } from '@angular/forms';
import { HasConfirmForm } from '@core/guards/confirm-on-exit.guard';
import { NotificationService } from '@core/http/notification.service';
import { NotificationSettings } from '@shared/models/notification.models';
import { deepTrim, isEmptyStr } from '@core/utils';
@Component({
selector: 'tb-notification-settings',
templateUrl: './notification-settings.component.html',
styleUrls: ['./settings-card.scss']
})
export class NotificationSettingsComponent extends PageComponent implements OnInit, HasConfirmForm {
notificationSettingsForm: FormGroup;
private notificationSettings: NotificationSettings;
constructor(protected store: Store<AppState>,
private notificationService: NotificationService,
public fb: FormBuilder) {
super(store);
}
ngOnInit() {
this.buildGeneralServerSettingsForm();
this.notificationService.getNotificationSettings().subscribe(
(settings) => {
this.notificationSettings = settings;
this.notificationSettingsForm.reset(this.notificationSettings);
}
);
}
buildGeneralServerSettingsForm() {
this.notificationSettingsForm = this.fb.group({
deliveryMethodsConfigs: this.fb.group({
SLACK: this.fb.group({
botToken: ['']
})
})
});
}
save(): void {
this.notificationSettings = deepTrim({
...this.notificationSettings,
...this.notificationSettingsForm.value
});
for (const method in this.notificationSettings.deliveryMethodsConfigs) {
const keys = Object.keys(this.notificationSettings.deliveryMethodsConfigs[method]);
if (keys.some(item => isEmptyStr(this.notificationSettings.deliveryMethodsConfigs[method][item]))) {
delete this.notificationSettings.deliveryMethodsConfigs[method];
} else {
this.notificationSettings.deliveryMethodsConfigs[method].method = method;
}
}
this.notificationService.saveNotificationSettings(this.notificationSettings).subscribe(setting => {
this.notificationSettings = setting;
this.notificationSettingsForm.reset(this.notificationSettings);
});
}
confirmForm(): FormGroup {
return this.notificationSettingsForm;
}
}

30
ui-ngx/src/app/modules/home/pages/admin/sms-provider.component.html

@ -47,4 +47,34 @@
</form> </form>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>
<mat-card appearance="outlined" class="settings-card">
<!-- <mat-card-header>-->
<!-- <mat-card-title>-->
<!-- <div fxLayout="row">-->
<!-- <span class="mat-headline-5" translate>admin.notifications-settings</span>-->
<!-- </div>-->
<!-- </mat-card-title>-->
<!-- </mat-card-header>-->
<mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async">
</mat-progress-bar>
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
<mat-card-content style="padding-top: 16px;">
<form [formGroup]="notificationSettingsForm" (ngSubmit)="saveNotification()">
<fieldset [disabled]="isLoading$ | async" formGroupName="deliveryMethodsConfigs">
<fieldset class="fields-group" formGroupName="SLACK">
<legend class="group-title" translate>admin.slack</legend>
<mat-form-field class="mat-block">
<mat-label translate>admin.slack-api-token</mat-label>
<input matInput formControlName="botToken" />
</mat-form-field>
</fieldset>
<div fxLayout="row" fxLayoutAlign="end center" class="layout-wrap">
<button mat-button mat-raised-button color="primary" [disabled]="(isLoading$ | async) || notificationSettingsForm.invalid || !notificationSettingsForm.dirty"
type="submit">{{'action.save' | translate}}
</button>
</div>
</fieldset>
</form>
</mat-card-content>
</mat-card>
</div> </div>

64
ui-ngx/src/app/modules/home/pages/admin/sms-provider.component.ts

@ -19,12 +19,15 @@ import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state'; import { AppState } from '@core/core.state';
import { PageComponent } from '@shared/components/page.component'; import { PageComponent } from '@shared/components/page.component';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AdminSettings, SmsProviderConfiguration } from '@shared/models/settings.models'; import { AdminSettings, SmsProviderConfiguration } from '@shared/models/settings.models';
import { AdminService } from '@core/http/admin.service'; import { AdminService } from '@core/http/admin.service';
import { HasConfirmForm } from '@core/guards/confirm-on-exit.guard'; import { HasConfirmForm } from '@core/guards/confirm-on-exit.guard';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { SendTestSmsDialogComponent, SendTestSmsDialogData } from '@home/pages/admin/send-test-sms-dialog.component'; import { SendTestSmsDialogComponent, SendTestSmsDialogData } from '@home/pages/admin/send-test-sms-dialog.component';
import { NotificationSettings } from '@shared/models/notification.models';
import { deepTrim, isEmptyStr } from '@core/utils';
import { NotificationService } from '@core/http/notification.service';
@Component({ @Component({
selector: 'tb-sms-provider', selector: 'tb-sms-provider',
@ -33,35 +36,46 @@ import { SendTestSmsDialogComponent, SendTestSmsDialogData } from '@home/pages/a
}) })
export class SmsProviderComponent extends PageComponent implements OnInit, HasConfirmForm { export class SmsProviderComponent extends PageComponent implements OnInit, HasConfirmForm {
smsProvider: UntypedFormGroup; smsProvider: FormGroup;
adminSettings: AdminSettings<SmsProviderConfiguration>; adminSettings: AdminSettings<SmsProviderConfiguration>;
notificationSettingsForm: FormGroup;
private notificationSettings: NotificationSettings;
constructor(protected store: Store<AppState>, constructor(protected store: Store<AppState>,
private router: Router, private router: Router,
private adminService: AdminService, private adminService: AdminService,
private notificationService: NotificationService,
private dialog: MatDialog, private dialog: MatDialog,
public fb: UntypedFormBuilder) { public fb: FormBuilder) {
super(store); super(store);
} }
ngOnInit() { ngOnInit() {
this.buildSmsProviderForm(); this.buildSmsProviderForm();
this.adminService.getAdminSettings<SmsProviderConfiguration>('sms', {ignoreErrors: true}).subscribe( this.buildGeneralServerSettingsForm();
(adminSettings) => { this.notificationService.getNotificationSettings().subscribe(
(settings) => {
this.notificationSettings = settings;
this.notificationSettingsForm.reset(this.notificationSettings);
}
);
this.adminService.getAdminSettings<SmsProviderConfiguration>('sms', {ignoreErrors: true}).subscribe({
next: adminSettings => {
this.adminSettings = adminSettings; this.adminSettings = adminSettings;
this.smsProvider.reset({configuration: this.adminSettings.jsonValue}); this.smsProvider.reset({configuration: this.adminSettings.jsonValue});
}, },
() => { error: () => {
this.adminSettings = { this.adminSettings = {
key: 'sms', key: 'sms',
jsonValue: null jsonValue: null
}; };
this.smsProvider.reset({configuration: this.adminSettings.jsonValue}); this.smsProvider.reset({configuration: this.adminSettings.jsonValue});
} }
); });
} }
buildSmsProviderForm() { private buildSmsProviderForm() {
this.smsProvider = this.fb.group({ this.smsProvider = this.fb.group({
configuration: [null, [Validators.required]] configuration: [null, [Validators.required]]
}); });
@ -88,8 +102,38 @@ export class SmsProviderComponent extends PageComponent implements OnInit, HasCo
); );
} }
confirmForm(): UntypedFormGroup { confirmForm(): FormGroup {
return this.smsProvider; return this.smsProvider.dirty ? this.smsProvider : this.notificationSettingsForm;
}
private buildGeneralServerSettingsForm() {
this.notificationSettingsForm = this.fb.group({
deliveryMethodsConfigs: this.fb.group({
SLACK: this.fb.group({
botToken: ['']
})
})
});
}
saveNotification(): void {
this.notificationSettings = deepTrim({
...this.notificationSettings,
...this.notificationSettingsForm.value
});
// eslint-disable-next-line guard-for-in
for (const method in this.notificationSettings.deliveryMethodsConfigs) {
const keys = Object.keys(this.notificationSettings.deliveryMethodsConfigs[method]);
if (keys.some(item => isEmptyStr(this.notificationSettings.deliveryMethodsConfigs[method][item]))) {
delete this.notificationSettings.deliveryMethodsConfigs[method];
} else {
this.notificationSettings.deliveryMethodsConfigs[method].method = method;
}
}
this.notificationService.saveNotificationSettings(this.notificationSettings).subscribe(setting => {
this.notificationSettings = setting;
this.notificationSettingsForm.reset(this.notificationSettings);
});
} }
} }

4
ui-ngx/src/app/modules/home/pages/notification/notification.module.ts

@ -36,6 +36,7 @@ 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: [
@ -51,7 +52,8 @@ import { RuleTableHeaderComponent } from '@home/pages/notification/rule/rule-tab
EscalationFormComponent, EscalationFormComponent,
EscalationsComponent, EscalationsComponent,
RuleNotificationDialogComponent, RuleNotificationDialogComponent,
RuleTableHeaderComponent RuleTableHeaderComponent,
SentTableHeaderComponent
], ],
imports: [ imports: [
CommonModule, CommonModule,

8
ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-table-config.resolver.ts

@ -16,6 +16,7 @@
import { import {
CellActionDescriptor, CellActionDescriptor,
DateEntityTableColumn,
EntityTableColumn, EntityTableColumn,
EntityTableConfig EntityTableConfig
} from '@home/models/entity/entities-table-config.models'; } from '@home/models/entity/entities-table-config.models';
@ -33,6 +34,7 @@ import { EntityAction } from '@home/models/entity/entity-component.models';
import { RecipientTableHeaderComponent } from '@home/pages/notification/recipient/recipient-table-header.component'; import { RecipientTableHeaderComponent } from '@home/pages/notification/recipient/recipient-table-header.component';
import { ActivatedRouteSnapshot, Resolve } from '@angular/router'; import { ActivatedRouteSnapshot, Resolve } from '@angular/router';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { DatePipe } from '@angular/common';
@Injectable() @Injectable()
export class RecipientTableConfigResolver implements Resolve<EntityTableConfig<NotificationTarget>> { export class RecipientTableConfigResolver implements Resolve<EntityTableConfig<NotificationTarget>> {
@ -41,7 +43,8 @@ export class RecipientTableConfigResolver implements Resolve<EntityTableConfig<N
constructor(private notificationService: NotificationService, constructor(private notificationService: NotificationService,
private translate: TranslateService, private translate: TranslateService,
private dialog: MatDialog) { private dialog: MatDialog,
private datePipe: DatePipe) {
this.config.detailsPanelEnabled = false; this.config.detailsPanelEnabled = false;
this.config.selectionEnabled = false; this.config.selectionEnabled = false;
@ -65,7 +68,7 @@ export class RecipientTableConfigResolver implements Resolve<EntityTableConfig<N
this.config.headerComponent = RecipientTableHeaderComponent; this.config.headerComponent = RecipientTableHeaderComponent;
this.config.onEntityAction = action => this.onTargetAction(action); this.config.onEntityAction = action => this.onTargetAction(action);
this.config.defaultSortOrder = {property: 'name', direction: Direction.ASC}; this.config.defaultSortOrder = {property: 'createdTime', direction: Direction.DESC};
this.config.handleRowClick = ($event, target) => { this.config.handleRowClick = ($event, target) => {
this.editTarget($event, target); this.editTarget($event, target);
@ -73,6 +76,7 @@ export class RecipientTableConfigResolver implements Resolve<EntityTableConfig<N
}; };
this.config.columns.push( this.config.columns.push(
new DateEntityTableColumn<NotificationTarget>('createdTime', 'notification.created-time', this.datePipe, '170px'),
new EntityTableColumn<NotificationTarget>('name', 'notification.notification-target', '20%'), new EntityTableColumn<NotificationTarget>('name', 'notification.notification-target', '20%'),
new EntityTableColumn<NotificationTarget>('configuration.type', 'notification.type', '20%', new EntityTableColumn<NotificationTarget>('configuration.type', 'notification.type', '20%',
(target) => this.translate.instant(NotificationTargetTypeTranslationMap.get(target.configuration.type)), (target) => this.translate.instant(NotificationTargetTypeTranslationMap.get(target.configuration.type)),

8
ui-ngx/src/app/modules/home/pages/notification/rule/rule-table-config.resolver.ts

@ -16,6 +16,7 @@
import { import {
CellActionDescriptor, CellActionDescriptor,
DateEntityTableColumn,
EntityTableColumn, EntityTableColumn,
EntityTableConfig EntityTableConfig
} from '@home/models/entity/entities-table-config.models'; } from '@home/models/entity/entities-table-config.models';
@ -33,6 +34,7 @@ import {
} from '@home/pages/notification/rule/rule-notification-dialog.component'; } from '@home/pages/notification/rule/rule-notification-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 { DatePipe } from '@angular/common';
@Injectable() @Injectable()
export class RuleTableConfigResolver implements Resolve<EntityTableConfig<NotificationRule>> { export class RuleTableConfigResolver implements Resolve<EntityTableConfig<NotificationRule>> {
@ -41,7 +43,8 @@ export class RuleTableConfigResolver implements Resolve<EntityTableConfig<Notifi
constructor(private notificationService: NotificationService, constructor(private notificationService: NotificationService,
private translate: TranslateService, private translate: TranslateService,
private dialog: MatDialog) { private dialog: MatDialog,
private datePipe: DatePipe) {
this.config.detailsPanelEnabled = false; this.config.detailsPanelEnabled = false;
this.config.selectionEnabled = false; this.config.selectionEnabled = false;
@ -64,7 +67,7 @@ export class RuleTableConfigResolver implements Resolve<EntityTableConfig<Notifi
this.config.headerComponent = RuleTableHeaderComponent; this.config.headerComponent = RuleTableHeaderComponent;
this.config.onEntityAction = action => this.onTargetAction(action); this.config.onEntityAction = action => this.onTargetAction(action);
this.config.defaultSortOrder = {property: 'name', direction: Direction.ASC}; this.config.defaultSortOrder = {property: 'createdTime', direction: Direction.DESC};
this.config.handleRowClick = ($event, rule) => { this.config.handleRowClick = ($event, rule) => {
this.editRule($event, rule); this.editRule($event, rule);
@ -72,6 +75,7 @@ export class RuleTableConfigResolver implements Resolve<EntityTableConfig<Notifi
}; };
this.config.columns.push( this.config.columns.push(
new DateEntityTableColumn<NotificationRule>('createdTime', 'notification.created-time', this.datePipe, '170px'),
new EntityTableColumn<NotificationRule>('name', 'notification.rule-name', '30%'), new EntityTableColumn<NotificationRule>('name', 'notification.rule-name', '30%'),
new EntityTableColumn<NotificationRule>('templateName', 'notification.template', '20%'), new EntityTableColumn<NotificationRule>('templateName', 'notification.template', '20%'),
new EntityTableColumn<NotificationRule>('triggerType', 'notification.trigger.trigger', '20%', new EntityTableColumn<NotificationRule>('triggerType', 'notification.trigger.trigger', '20%',

2
ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-config.resolver.ts

@ -47,6 +47,7 @@ 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,6 +78,7 @@ 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) => {

24
ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.html

@ -0,0 +1,24 @@
<!--
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="100" fxLayout="row" fxLayoutAlign="end center">
<button mat-flat-button color="primary" (click)="sendNotification($event)">
<div fxLayout="row" fxLayoutAlign="start center">
<mat-icon>send</mat-icon>{{ 'notification.send-notification' | translate }}
</div>
</button>
</div>

18
ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.scss

@ -0,0 +1,18 @@
/**
* 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;
}

39
ui-ngx/src/app/modules/home/pages/notification/sent/sent-table-header.component.ts

@ -0,0 +1,39 @@
///
/// 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});
}
}

8
ui-ngx/src/app/modules/home/pages/notification/template/template-table-config.resolver.ts

@ -16,6 +16,7 @@
import { import {
CellActionDescriptor, CellActionDescriptor,
DateEntityTableColumn,
EntityTableColumn, EntityTableColumn,
EntityTableConfig EntityTableConfig
} from '@home/models/entity/entities-table-config.models'; } from '@home/models/entity/entities-table-config.models';
@ -33,6 +34,7 @@ import { TranslateService } from '@ngx-translate/core';
import { TemplateTableHeaderComponent } from '@home/pages/notification/template/template-table-header.component'; import { TemplateTableHeaderComponent } from '@home/pages/notification/template/template-table-header.component';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve } from '@angular/router'; import { ActivatedRouteSnapshot, Resolve } from '@angular/router';
import { DatePipe } from '@angular/common';
@Injectable() @Injectable()
export class TemplateTableConfigResolver implements Resolve<EntityTableConfig<NotificationTemplate>> { export class TemplateTableConfigResolver implements Resolve<EntityTableConfig<NotificationTemplate>> {
@ -41,7 +43,8 @@ export class TemplateTableConfigResolver implements Resolve<EntityTableConfig<No
constructor(private notificationService: NotificationService, constructor(private notificationService: NotificationService,
private translate: TranslateService, private translate: TranslateService,
private dialog: MatDialog) { private dialog: MatDialog,
private datePipe: DatePipe) {
this.config.detailsPanelEnabled = false; this.config.detailsPanelEnabled = false;
this.config.selectionEnabled = false; this.config.selectionEnabled = false;
@ -65,7 +68,7 @@ export class TemplateTableConfigResolver implements Resolve<EntityTableConfig<No
this.config.headerComponent = TemplateTableHeaderComponent; this.config.headerComponent = TemplateTableHeaderComponent;
this.config.onEntityAction = action => this.onTemplateAction(action); this.config.onEntityAction = action => this.onTemplateAction(action);
this.config.defaultSortOrder = {property: 'notificationType', direction: Direction.ASC}; this.config.defaultSortOrder = {property: 'createdTime', direction: Direction.DESC};
this.config.handleRowClick = ($event, template) => { this.config.handleRowClick = ($event, template) => {
this.editTemplate($event, template); this.editTemplate($event, template);
@ -73,6 +76,7 @@ export class TemplateTableConfigResolver implements Resolve<EntityTableConfig<No
}; };
this.config.columns.push( this.config.columns.push(
new DateEntityTableColumn<NotificationTemplate>('createdTime', 'notification.created-time', this.datePipe, '170px'),
new EntityTableColumn<NotificationTemplate>('notificationType', 'notification.type', '15%', new EntityTableColumn<NotificationTemplate>('notificationType', 'notification.type', '15%',
(template) => this.translate.instant(NotificationTemplateTypeTranslateMap.get(template.notificationType).name)), (template) => this.translate.instant(NotificationTemplateTypeTranslateMap.get(template.notificationType).name)),
new EntityTableColumn<NotificationTemplate>('name', 'notification.template', '25%'), new EntityTableColumn<NotificationTemplate>('name', 'notification.template', '25%'),

2
ui-ngx/src/app/shared/components/notification/notification.component.scss

@ -29,6 +29,7 @@
.content { .content {
letter-spacing: .25px; letter-spacing: .25px;
word-break: break-word;
.title { .title {
margin-bottom: 4px; margin-bottom: 4px;
font-weight: 500; font-weight: 500;
@ -37,7 +38,6 @@
font-size: 14px; font-size: 14px;
line-height: 16px; line-height: 16px;
color: rgba(0, 0, 0, 0.76); color: rgba(0, 0, 0, 0.76);
word-break: break-word;
} }
.button { .button {

7
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -415,11 +415,8 @@
"resources": "Resources", "resources": "Resources",
"notifications": "Notifications", "notifications": "Notifications",
"notifications-settings": "Notifications settings", "notifications-settings": "Notifications settings",
"notification": { "slack-api-token": "Slack api token",
"notification-settings": "Notification settings", "slack": "Slack"
"slack-api-token": "Slack api token",
"slack": "Slack"
}
}, },
"alarm": { "alarm": {
"alarm": "Alarm", "alarm": "Alarm",

Loading…
Cancel
Save