Browse Source

UI: Change notification recipients models

pull/8046/head
Vladyslav_Prykhodko 4 years ago
parent
commit
e3057ffe24
  1. 2
      ui-ngx/src/app/core/http/entity.service.ts
  2. 5
      ui-ngx/src/app/core/http/notification.service.ts
  3. 7
      ui-ngx/src/app/modules/home/pages/notification-center/notification-table/targets-table-config.ts
  4. 64
      ui-ngx/src/app/modules/home/pages/notification-center/targets-table/target-notification-dialog.component.html
  5. 39
      ui-ngx/src/app/modules/home/pages/notification-center/targets-table/target-notification-dialog.componet.scss
  6. 42
      ui-ngx/src/app/modules/home/pages/notification-center/targets-table/target-notification-dialog.componet.ts
  7. 27
      ui-ngx/src/app/shared/models/notification.models.ts
  8. 2
      ui-ngx/src/assets/locale/locale.constant-en_US.json

2
ui-ngx/src/app/core/http/entity.service.ts

@ -252,7 +252,7 @@ export class EntityService {
entityIds);
break;
case EntityType.NOTIFICATION_TARGET:
observable = of([]);
observable = this.notificationService.getNotificationTargetsByIds(entityIds, config);
break;
}
return observable;

5
ui-ngx/src/app/core/http/notification.service.ts

@ -122,6 +122,11 @@ export class NotificationService {
return this.http.delete<void>(`/api/notification/target/${id}`, defaultHttpOptionsFromConfig(config));
}
public getNotificationTargetsByIds(ids: string[], config?: RequestConfig): Observable<Array<NotificationTarget>> {
return this.http.get<Array<NotificationTarget>>(`/api/notification/targets?ids=${ids.join(',')}`,
defaultHttpOptionsFromConfig(config));
}
public getNotificationTargets(pageLink: PageLink, config?: RequestConfig): Observable<PageData<NotificationTarget>> {
return this.http.get<PageData<NotificationTarget>>(`/api/notification/targets${pageLink.toQuery()}`,
defaultHttpOptionsFromConfig(config));

7
ui-ngx/src/app/modules/home/pages/notification-center/notification-table/targets-table-config.ts

@ -21,7 +21,7 @@ import {
} from '@home/models/entity/entities-table-config.models';
import { EntityTypeResource } from '@shared/models/entity-type.models';
import { Direction } from '@shared/models/page/sort-order';
import { NotificationTarget, NotificationTargetConfigTypeTranslateMap } from '@shared/models/notification.models';
import { NotificationTarget, NotificationTargetTypeTranslationMap } from '@shared/models/notification.models';
import { NotificationService } from '@core/http/notification.service';
import { TranslateService } from '@ngx-translate/core';
import {
@ -62,9 +62,8 @@ export class TargetsTableConfig extends EntityTableConfig<NotificationTarget> {
this.columns.push(
new EntityTableColumn<NotificationTarget>('name', 'notification.notification-target', '20%'),
new EntityTableColumn<NotificationTarget>('configuration.type', 'notification.type', '40%',
(target) => this.translate.instant(NotificationTargetConfigTypeTranslateMap.get(target.configuration.type)),
() => ({}), false),
new EntityTableColumn<NotificationTarget>('type', 'notification.type', '40%',
(target) => this.translate.instant(NotificationTargetTypeTranslationMap.get(target.type))),
new EntityTableColumn<NotificationTarget>('configuration.description', 'notification.description', '40%',
(target) => target.configuration.description || '',
() => ({}), false)

64
ui-ngx/src/app/modules/home/pages/notification-center/targets-table/target-notification-dialog.component.html

@ -36,35 +36,45 @@
{{ 'notification.target-name-required' | translate }}
</mat-error>
</mat-form-field>
<mat-radio-group formControlName="type">
<mat-radio-button *ngFor="let notificationTargetType of notificationTargetTypes" [value]="notificationTargetType">
<div fxLayout="column">
<div>{{ notificationTargetTypeTranslationMap.get(notificationTargetType) | translate }}</div>
</div>
</mat-radio-button>
</mat-radio-group>
<section formGroupName="configuration">
<mat-form-field class="mat-block">
<mat-label translate>notification.target-type.type</mat-label>
<mat-select formControlName="type">
<mat-option *ngFor="let type of notificationTargetConfigTypes" [value]="type">
{{ notificationTargetConfigTypeTranslateMap.get(type) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<tb-entity-list
required
formControlName="usersIds"
[entityType]="entityType.USER"
labelText="user.user-list"
placeholderText="user.user"
requiredText="user.user-list-required"
*ngIf="targetNotificationForm.get('configuration.type').value === notificationTargetConfigType.USER_LIST">
</tb-entity-list>
<section
*ngIf="targetNotificationForm.get('configuration.type').value === notificationTargetConfigType.CUSTOMER_USERS">
<mat-slide-toggle formControlName="getCustomerIdFromOriginatorEntity">
{{ 'notification.get-customer-id-from-originator' | translate }}
</mat-slide-toggle>
<tb-entity-autocomplete
<section formGroupName="usersFilter"
*ngIf="targetNotificationForm.get('type').value === notificationTargetType.PLATFORM_USERS">
<mat-form-field class="mat-block">
<mat-label translate>notification.target-type.type</mat-label>
<mat-select formControlName="type">
<mat-option *ngFor="let type of notificationTargetConfigTypes" [value]="type">
{{ notificationTargetConfigTypeTranslateMap.get(type) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<tb-entity-list
required
formControlName="customerId"
[entityType]="entityType.CUSTOMER"
*ngIf="!targetNotificationForm.get('configuration.getCustomerIdFromOriginatorEntity').value">
</tb-entity-autocomplete>
formControlName="usersIds"
[entityType]="entityType.USER"
labelText="user.user-list"
placeholderText="user.user"
requiredText="user.user-list-required"
*ngIf="targetNotificationForm.get('configuration.usersFilter.type').value === notificationTargetConfigType.USER_LIST">
</tb-entity-list>
<section
*ngIf="targetNotificationForm.get('configuration.usersFilter.type').value === notificationTargetConfigType.CUSTOMER_USERS">
<mat-slide-toggle formControlName="getCustomerIdFromOriginatorEntity">
{{ 'notification.get-customer-id-from-originator' | translate }}
</mat-slide-toggle>
<tb-entity-autocomplete
required
formControlName="customerId"
[entityType]="entityType.CUSTOMER"
*ngIf="!targetNotificationForm.get('configuration.usersFilter.getCustomerIdFromOriginatorEntity').value">
</tb-entity-autocomplete>
</section>
</section>
<mat-form-field class="mat-block">
<mat-label translate>notification.description</mat-label>

39
ui-ngx/src/app/modules/home/pages/notification-center/targets-table/target-notification-dialog.componet.scss

@ -0,0 +1,39 @@
/**
* Copyright © 2016-2022 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 "../../../../../../theme";
:host ::ng-deep {
.mat-radio-group {
display: flex;
flex-direction: row;
margin-bottom: 8px;
.mat-radio-button {
flex: 1 1 100%;
padding: 14px;
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 6px;
&:not(:last-child){
margin-right: 8px;
}
&.mat-radio-checked {
border-color: map_get($tb-accent, 500);
}
}
}
}

42
ui-ngx/src/app/modules/home/pages/notification-center/targets-table/target-notification-dialog.componet.ts

@ -17,7 +17,9 @@
import {
NotificationTarget,
NotificationTargetConfigType,
NotificationTargetConfigTypeTranslateMap
NotificationTargetConfigTypeTranslateMap,
NotificationTargetType,
NotificationTargetTypeTranslationMap
} from '@shared/models/notification.models';
import { Component, Inject, OnDestroy } from '@angular/core';
import { DialogComponent } from '@shared/components/dialog.component';
@ -40,12 +42,15 @@ export interface TargetsNotificationDialogData {
@Component({
selector: 'tb-target-notification-dialog',
templateUrl: './target-notification-dialog.component.html',
styleUrls: []
styleUrls: ['target-notification-dialog.componet.scss']
})
export class TargetNotificationDialogComponent extends
DialogComponent<TargetNotificationDialogComponent, NotificationTarget> implements OnDestroy {
targetNotificationForm: FormGroup;
notificationTargetType = NotificationTargetType;
notificationTargetTypes: NotificationTargetType[] = Object.values(NotificationTargetType);
notificationTargetTypeTranslationMap = NotificationTargetTypeTranslationMap;
notificationTargetConfigType = NotificationTargetConfigType;
notificationTargetConfigTypes: NotificationTargetConfigType[] = Object.values(NotificationTargetConfigType);
notificationTargetConfigTypeTranslateMap = NotificationTargetConfigTypeTranslateMap;
@ -68,44 +73,46 @@ export class TargetNotificationDialogComponent extends
this.targetNotificationForm = this.fb.group({
name: [null, Validators.required],
type: [NotificationTargetType.PLATFORM_USERS],
configuration: this.fb.group({
type: [NotificationTargetConfigType.ALL_USERS],
description: [null],
usersIds: [{value: null, disabled: true}, Validators.required],
customerId: [{value: null, disabled: true}, Validators.required],
getCustomerIdFromOriginatorEntity: [{value: false, disabled: true}],
usersFilter: this.fb.group({
type: [NotificationTargetConfigType.ALL_USERS],
usersIds: [{value: null, disabled: true}, Validators.required],
customerId: [{value: null, disabled: true}, Validators.required],
getCustomerIdFromOriginatorEntity: [{value: false, disabled: true}]
})
})
});
this.targetNotificationForm.get('configuration.type').valueChanges.pipe(
this.targetNotificationForm.get('configuration.usersFilter.type').valueChanges.pipe(
takeUntil(this.destroy$)
).subscribe((type: NotificationTargetConfigType) => {
this.targetNotificationForm.get('configuration').disable({emitEvent: false});
this.targetNotificationForm.get('configuration.usersFilter').disable({emitEvent: false});
switch (type) {
case NotificationTargetConfigType.USER_LIST:
this.targetNotificationForm.get('configuration.usersIds').enable({emitEvent: false});
this.targetNotificationForm.get('configuration.usersFilter.usersIds').enable({emitEvent: false});
break;
case NotificationTargetConfigType.CUSTOMER_USERS:
this.targetNotificationForm.get('configuration.getCustomerIdFromOriginatorEntity').enable({emitEvent: false});
this.targetNotificationForm.get('configuration.getCustomerIdFromOriginatorEntity').updateValueAndValidity({onlySelf: true});
this.targetNotificationForm.get('configuration.usersFilter.getCustomerIdFromOriginatorEntity').enable({onlySelf: true});
break;
}
this.targetNotificationForm.get('configuration.type').enable({emitEvent: false});
this.targetNotificationForm.get('configuration.description').enable({emitEvent: false});
this.targetNotificationForm.get('configuration.usersFilter.type').enable({emitEvent: false});
});
this.targetNotificationForm.get('configuration.getCustomerIdFromOriginatorEntity').valueChanges.pipe(
this.targetNotificationForm.get('configuration.usersFilter.getCustomerIdFromOriginatorEntity').valueChanges.pipe(
takeUntil(this.destroy$)
).subscribe((value: boolean) => {
if (value) {
this.targetNotificationForm.get('configuration.customerId').disable({emitEvent: false});
this.targetNotificationForm.get('configuration.usersFilter.customerId').disable({emitEvent: false});
} else {
this.targetNotificationForm.get('configuration.customerId').enable({emitEvent: false});
this.targetNotificationForm.get('configuration.usersFilter.customerId').enable({emitEvent: false});
}
});
if (isDefined(data.target)) {
this.targetNotificationForm.patchValue(data.target, {emitEvent: false});
this.targetNotificationForm.get('configuration.type').updateValueAndValidity({onlySelf: true});
this.targetNotificationForm.get('type').updateValueAndValidity({onlySelf: true});
this.targetNotificationForm.get('configuration.usersFilter.type').updateValueAndValidity({onlySelf: true});
}
}
@ -124,6 +131,7 @@ export class TargetNotificationDialogComponent extends
if (isDefined(this.data.target)) {
formValue = Object.assign({}, this.data.target, formValue);
}
formValue.configuration.type = formValue.type;
this.notificationService.saveNotificationTarget(formValue).subscribe(
(target) => this.dialogRef.close(target)
);

27
ui-ngx/src/app/shared/models/notification.models.ts

@ -120,13 +120,21 @@ export interface NonConfirmedNotificationEscalation {
export interface NotificationTarget extends Omit<BaseData<NotificationTargetId>, 'label'>{
tenantId: TenantId;
type: NotificationTargetType;
configuration: NotificationTargetConfig;
}
export interface NotificationTargetConfig extends
export interface NotificationTargetConfig extends Partial<PlatformUsersNotificationTargetConfig & SlackNotificationTargetConfig> {
description?: string;
type: NotificationTargetType;
}
export interface PlatformUsersNotificationTargetConfig {
usersFilter: UsersFilter;
}
export interface UsersFilter extends
Partial<UserListNotificationTargetConfig & CustomerUsersNotificationTargetConfig>{
type: NotificationTargetConfigType;
description?: string;
}
interface UserListNotificationTargetConfig {
@ -138,6 +146,21 @@ interface CustomerUsersNotificationTargetConfig {
getCustomerIdFromOriginatorEntity: boolean;
}
export interface SlackNotificationTargetConfig {
conversationType: SlackConversation;
conversationId: string;
conversationName: string;
}
export enum NotificationTargetType {
PLATFORM_USERS = 'PLATFORM_USERS',
SLACK = 'SLACK'
}
export const NotificationTargetTypeTranslationMap = new Map<NotificationTargetType, string>([
[NotificationTargetType.PLATFORM_USERS, 'notification.platform-users'],
[NotificationTargetType.SLACK, 'notification.slack']
]);
export interface NotificationTemplate extends Omit<BaseData<NotificationTemplateId>, 'label'>{
tenantId: TenantId;
notificationType: NotificationType;

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

@ -2733,6 +2733,7 @@
},
"review": "Review",
"rules": "Rules",
"platform-users": "Platform users",
"search-notification": "Search notification",
"search-targets": "Search recipients",
"search-templates": "Search templates",
@ -2740,6 +2741,7 @@
"send-test-notification": "Send test notification",
"sent": "Sent",
"settings": "Notification settings",
"slack": "Slack",
"slack-chanel-type": "Slack chanel type",
"slack-chanel-types": {
"direct": "Direct message",

Loading…
Cancel
Save