diff --git a/ui-ngx/src/app/modules/home/pages/notification-center/notification-table/rule-table-config.ts b/ui-ngx/src/app/modules/home/pages/notification-center/notification-table/rule-table-config.ts index 732fa8e16e..b62c111509 100644 --- a/ui-ngx/src/app/modules/home/pages/notification-center/notification-table/rule-table-config.ts +++ b/ui-ngx/src/app/modules/home/pages/notification-center/notification-table/rule-table-config.ts @@ -24,7 +24,7 @@ import { Direction } from '@shared/models/page/sort-order'; import { NotificationRule, NotificationTarget, - NotificationTargetConfigTypeTranslateMap + NotificationTargetConfigTypeTranslateMap, TriggerTypeTranslationMap } from '@shared/models/notification.models'; import { NotificationService } from '@core/http/notification.service'; import { TranslateService } from '@ngx-translate/core'; @@ -62,8 +62,7 @@ export class RuleTableConfig extends EntityTableConfig { this.deleteEntityContent = () => this.translate.instant('notification.delete-rule-text'); this.deleteEntity = id => this.notificationService.deleteNotificationRule(id.id); - this.cellActionDescriptors = this.configureCellActions(); - + // this.cellActionDescriptors = this.configureCellActions(); this.headerComponent = RuleTableHeaderComponent; this.onEntityAction = action => this.onTargetAction(action); @@ -71,12 +70,12 @@ export class RuleTableConfig extends EntityTableConfig { this.columns.push( new EntityTableColumn('name', 'notification.rule-name', '30%'), - new EntityTableColumn('templateId', 'notification.template', '30%', - (rule) => `${rule.templateId}`, + new EntityTableColumn('templateId', 'notification.template', '15%', + (rule) => `${rule.templateId.id}`, () => ({}), false), - new EntityTableColumn('configuration.description', 'notification.description', '40%', - (rule) => rule.configuration.description || '', - () => ({}), false) + new EntityTableColumn('triggerType', 'notification.trigger.trigger', '15%', + (rule) => this.translate.instant(TriggerTypeTranslationMap.get(rule.triggerType)) || '', + () => ({}), true) ); } diff --git a/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalation-form.component.html b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalation-form.component.html index ab12a8d541..b6bac29dfb 100644 --- a/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalation-form.component.html +++ b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalation-form.component.html @@ -17,22 +17,23 @@ -->
-
-
-
notification.first-recipient
-
- After +
+
+
notification.first-recipient
+
+ After - notification.notify + [disabledAdvanced]="true"> + notification.notify
-
+
diff --git a/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalation-form.component.scss b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalation-form.component.scss new file mode 100644 index 0000000000..f80a0a7cef --- /dev/null +++ b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalation-form.component.scss @@ -0,0 +1,34 @@ +/** + * 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. + */ + +:host { + .escalation { + height: 100%; + min-height: 74px; + max-height: 100%; + border-radius: 8px; + background: rgba(0,0,0,0.04); + } + + .escalation-padding { + padding: 0 10px; + } + + .escalation-notify { + text-align: end; + padding: 0 10px; + } +} diff --git a/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalation-form.component.ts b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalation-form.component.ts index f68f6e2bc5..3c0ebf5b14 100644 --- a/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalation-form.component.ts +++ b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalation-form.component.ts @@ -22,18 +22,20 @@ import { FormGroup, NG_VALIDATORS, NG_VALUE_ACCESSOR, - Validator, Validators + Validator, + Validators } from '@angular/forms'; import { UtilsService } from '@core/services/utils.service'; import { isDefinedAndNotNull } from '@core/utils'; -import { Subscription } from 'rxjs'; +import { Subject } from 'rxjs'; import { NonConfirmedNotificationEscalation } from '@shared/models/notification.models'; import { EntityType } from '@shared/models/entity-type.models'; +import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'tb-escalation-form', templateUrl: './escalation-form.component.html', - styleUrls: [], + styleUrls: ['./escalation-form.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, @@ -59,10 +61,10 @@ export class EscalationFormComponent implements ControlValueAccessor, OnInit, On entityType = EntityType; - private modelValue: NonConfirmedNotificationEscalation; + private modelValue; private propagateChange = null; private propagateChangePending = false; - private valueChange$: Subscription = null; + private destroy$ = new Subject(); constructor(private utils: UtilsService, private fb: FormBuilder) { @@ -84,19 +86,17 @@ export class EscalationFormComponent implements ControlValueAccessor, OnInit, On ngOnInit() { this.escalationFormGroup = this.fb.group( { - delayInSec: [null], - notificationTargetId: [null, Validators.required], + delayInSec: [0], + targets: [null, Validators.required], }); - this.valueChange$ = this.escalationFormGroup.valueChanges.subscribe(() => { - this.updateModel(); - }); + this.escalationFormGroup.valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe(() => this.updateModel()); } ngOnDestroy() { - if (this.valueChange$) { - this.valueChange$.unsubscribe(); - this.valueChange$ = null; - } + this.destroy$.next(); + this.destroy$.complete(); } setDisabledState(isDisabled: boolean): void { diff --git a/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalations.component.ts b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalations.component.ts index fa8e90ce6c..578355e8d3 100644 --- a/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalations.component.ts +++ b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/escalations.component.ts @@ -30,11 +30,10 @@ import { import { Store } from '@ngrx/store'; import { AppState } from '@app/core/core.state'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; -import { Subscription } from 'rxjs'; -import { QueueInfo } from '@shared/models/queue.models'; +import { Subject } from 'rxjs'; import { UtilsService } from '@core/services/utils.service'; -import { guid } from '@core/utils'; import { NonConfirmedNotificationEscalation } from '@shared/models/notification.models'; +import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'tb-escalations-component', @@ -71,11 +70,11 @@ export class EscalationsComponent implements ControlValueAccessor, Validator, On disabled: boolean; private mainEscalaion = { - delayInSec: null, - notificationTargetId: null + delayInSec: 0, + targets: null }; - private valueChangeSubscription$: Subscription = null; + private destroy$ = new Subject(); private propagateChange = (v: any) => { }; @@ -89,9 +88,8 @@ export class EscalationsComponent implements ControlValueAccessor, Validator, On } ngOnDestroy() { - if (this.valueChangeSubscription$) { - this.valueChangeSubscription$.unsubscribe(); - } + this.destroy$.next(); + this.destroy$.complete(); } registerOnTouched(fn: any): void { @@ -101,6 +99,10 @@ export class EscalationsComponent implements ControlValueAccessor, Validator, On this.escalationsFormGroup = this.fb.group({ escalations: this.fb.array([]) }); + + this.escalationsFormGroup.valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe(() => this.updateModel()); } get escalationsFormArray(): FormArray { @@ -117,26 +119,24 @@ export class EscalationsComponent implements ControlValueAccessor, Validator, On } writeValue(escalations: Array | null): void { - if (this.valueChangeSubscription$) { - this.valueChangeSubscription$.unsubscribe(); - } - const escalationsControls: Array = []; - if (escalations) { - escalations.forEach((escalation, index) => { - escalationsControls.push(this.fb.control(escalation, [Validators.required])); - }); + if (escalations?.length === this.escalationsFormArray.length) { + this.escalationsFormArray.patchValue(escalations, {emitEvent: false}); } else { - escalationsControls.push(this.fb.control(this.mainEscalaion, [Validators.required])); + const escalationsControls: Array = []; + if (escalations) { + escalations.forEach((escalation, index) => { + escalationsControls.push(this.fb.control(escalation, [Validators.required])); + }); + } else { + escalationsControls.push(this.fb.control(this.mainEscalaion, [Validators.required])); + } + this.escalationsFormGroup.setControl('escalations', this.fb.array(escalationsControls), {emitEvent: false}); + if (this.disabled) { + this.escalationsFormGroup.disable({emitEvent: false}); + } else { + this.escalationsFormGroup.enable({emitEvent: false}); + } } - this.escalationsFormGroup.setControl('escalations', this.fb.array(escalationsControls)); - if (this.disabled) { - this.escalationsFormGroup.disable({emitEvent: false}); - } else { - this.escalationsFormGroup.enable({emitEvent: false}); - } - this.valueChangeSubscription$ = this.escalationsFormGroup.valueChanges.subscribe(() => - this.updateModel() - ); } public removeEscalation(index: number) { @@ -144,9 +144,9 @@ export class EscalationsComponent implements ControlValueAccessor, Validator, On } public addEscalation() { - const escalation: NonConfirmedNotificationEscalation = { - delayInSec: null, - notificationTargetId: null + const escalation = { + delayInSec: 0, + targets: null }; this.newEscalation = true; const escalationArray = this.escalationsFormGroup.get('escalations') as FormArray; @@ -166,7 +166,7 @@ export class EscalationsComponent implements ControlValueAccessor, Validator, On } private updateModel() { - const escalations: Array = this.escalationsFormGroup.get('escalations').value; + const escalations = this.escalationsFormGroup.get('escalations').value; this.propagateChange(escalations); } } diff --git a/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/rule-notification-dialog.component.html b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/rule-notification-dialog.component.html index 344f5a96ad..5a8c963b89 100644 --- a/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/rule-notification-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/rule-notification-dialog.component.html @@ -15,224 +15,231 @@ limitations under the License. --> - - -

{{'notification.add-rule' | translate }}

- - -
- - -
-
- - - check - - - {{ 'notification.basic-settings' | translate }} - - - notification.rule-name - - - {{ 'notification.rule-name-required' | translate }} - - - - - - notification.trigger.trigger - - - {{ triggerTypeTranslationMap.get(trigger) | translate }} - - - - {{ 'notification.trigger.trigger-required' | translate }} - - - - - - {{ 'notification.type-settings' | translate }} -
-
- notification.filter - - alarm.alarm-type-list - - - {{type}} - cancel - - - +
+ +

{{'notification.add-rule' | translate }}

+ + +
+ + +
+
+ + + check + + + {{ 'notification.basic-settings' | translate }} + + + notification.rule-name + + + {{ 'notification.rule-name-required' | translate }} + - - - alarm.alarm-severity-list - - - {{ alarmSeverityTranslationMap.get(severity) | translate }} - cancel - - - - - - - - -
-
- notification.no-severity-found -
- - - {{ translate.get('notification.no-severity-matching', - {severity: truncate.transform(severitySearchText, true, 6, '...')}) | async }} - - -
-
-
-
-
- -
- notification.clear-rule - - alarm.alarm-status-list - - - {{ alarmSearchStatusTranslationMap.get(searchStatus) | translate }} + + + + notification.trigger.trigger + + + {{ triggerTypeTranslationMap.get(trigger) | translate }} + + {{ 'notification.trigger.trigger-required' | translate }} + -
+
+
+ + {{ 'notification.type-settings' | translate }} +
+
+ notification.filter + + alarm.alarm-type-list + + + {{type}} + cancel + + + + -
- notification.hierarchy-of-receiving - -
+ + alarm.alarm-severity-list + + + {{ alarmSeverityTranslationMap.get(severity) | translate }} + cancel + + + + + + + + +
+
+ notification.no-severity-found +
+ + + {{ translate.get('notification.no-severity-matching', + {severity: truncate.transform(severitySearchText, true, 6, '...')}) | async }} + + +
+
+
+
+
- - notification.description - - -
-
+
+ notification.clear-rule + + alarm.alarm-status-list + + + {{ alarmSearchStatusTranslationMap.get(searchStatus) | translate }} + + + +
- - {{ 'notification.type-settings' | translate }} -
- notification.filter-by -
- - {{ 'notification.device' | translate }} - {{ 'notification.device-profile' | translate }} - -
- - - - - - - - notification.description - - -
-
+
+ notification.hierarchy-of-receiving + +
- - {{ 'notification.type-settings' | translate }} -
-
- notification.filter - - -
- notification.status - {{ 'notification.created' | translate }} - {{ 'notification.updated' | translate }} - {{ 'notification.deleted' | translate }} -
-
- - - - notification.description - - -
-
-
-
- -
- - - -
+ + notification.description + + + + + + + {{ 'notification.type-settings' | translate }} +
+ notification.filter-by +
+ + {{ 'notification.device' | translate }} + {{ 'notification.device-profile' | translate }} + +
+ + + + + + + + notification.description + + +
+
+ + + {{ 'notification.type-settings' | translate }} +
+
+ notification.filter + + +
+ notification.status + {{ 'notification.created' | translate }} + {{ 'notification.updated' | translate }} + {{ 'notification.deleted' | translate }} +
+
+ + + + notification.description + + +
+
+ +
+ +
+ + + +
+ diff --git a/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/rule-notification-dialog.component.scss b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/rule-notification-dialog.component.scss index 308c7170b2..7368d011fb 100644 --- a/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/rule-notification-dialog.component.scss +++ b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/rule-notification-dialog.component.scss @@ -17,9 +17,9 @@ :host { ::ng-deep{ - width: 100%; - min-width: 800px !important; - max-width: 100%; + //width: 100%; + //min-width: 800px; + //max-width: 100%; .mat-button-toggle-group.tb-notification-unread-toggle-group { &.mat-button-toggle-group-appearance-standard { diff --git a/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/rule-notification-dialog.component.ts b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/rule-notification-dialog.component.ts index 24f3068b13..bef3aad67f 100644 --- a/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/rule-notification-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/pages/notification-center/rule-table/rule-notification-dialog.component.ts @@ -23,10 +23,10 @@ import { Router } from '@angular/router'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { NotificationService } from '@core/http/notification.service'; -import { EntityType, entityTypeTranslations } from '@shared/models/entity-type.models'; +import { EntityType } from '@shared/models/entity-type.models'; import { deepTrim, isDefined } from '@core/utils'; import { Observable, of, Subject } from 'rxjs'; -import { map, mergeMap, share, startWith } from 'rxjs/operators'; +import { map, mergeMap, share, startWith, takeUntil } from 'rxjs/operators'; import { StepperOrientation, StepperSelectionEvent } from '@angular/cdk/stepper'; import { MatStepper } from '@angular/material/stepper'; import { MediaBreakpoints } from '@shared/models/constants'; @@ -34,12 +34,11 @@ import { BreakpointObserver } from '@angular/cdk/layout'; import { MatChipInputEvent, MatChipList } from '@angular/material/chips'; import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes'; import { - AlarmSearchStatus, - alarmSearchStatusTranslations, AlarmSeverity, - alarmSeverityTranslations + alarmSeverityTranslations, + AlarmStatus, + alarmStatusTranslations } from '@shared/models/alarm.models'; -import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; import { MatAutocomplete, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; import { TranslateService } from '@ngx-translate/core'; import { TruncatePipe } from '@shared/pipe/truncate.pipe'; @@ -80,11 +79,8 @@ export class RuleNotificationDialogComponent extends alarmSeverityEnum = AlarmSeverity; alarmSeverityTranslationMap = alarmSeverityTranslations; - alarmSearchStatuses = [AlarmSearchStatus.ACTIVE, - AlarmSearchStatus.CLEARED, - AlarmSearchStatus.ACK, - AlarmSearchStatus.UNACK]; - alarmSearchStatusTranslationMap = alarmSearchStatusTranslations; + alarmSearchStatuses = Object.values(AlarmStatus); + alarmSearchStatusTranslationMap = alarmStatusTranslations; entityType = EntityType; entityTypes = Object.values(EntityType); @@ -97,7 +93,7 @@ export class RuleNotificationDialogComponent extends severityInputChange = new Subject(); - private readonly destroy$ = new Subject(); + private destroy$ = new Subject(); constructor(protected store: Store, protected router: Router, @@ -120,39 +116,54 @@ export class RuleNotificationDialogComponent extends this.ruleNotificationForm = this.fb.group({ name: [null, Validators.required], templateId: [null, Validators.required], - trigger: [this.triggerType.ALARM, Validators.required], - configuration: this.fb.group({ - escalationConfig: this.fb.group({ - escalations: [[]] - }), - description: [null] + triggerType: [null, Validators.required], + recipientsConfig: this.fb.group({ + triggerType: [], + }), + triggerConfig: this.fb.group({ + triggerType: [] }) }); + this.ruleNotificationForm.get('triggerType').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe( + value => { + this.ruleNotificationForm.get('triggerConfig').patchValue({triggerType: value}, {emitEvent: false}); + this.ruleNotificationForm.get('recipientsConfig').patchValue({triggerType: value}, {emitEvent: false}); + } + ); + this.alarmTemplateForm = this.fb.group({ - alarmTypeList: [[], Validators.required], - alarmSeverityList: [[], Validators.required], - alarmStatusList: [[], Validators.required], - escalationConfig: [], + alarmTypes: [[], Validators.required], + alarmSeverities: [[], Validators.required], + clearRule: this.fb.group({ + alarmStatus: [] + }), + escalationTable: [], description: [''] }); this.deviceInactivityTemplateForm = this.fb.group({ filterByDevice: [true], - deviceId: [], - deviceProfileId: [], - notificationTargetId: [], + devices: [], + deviceProfiles: [], + targets: [[], Validators.required], description: [''] }); + this.deviceInactivityTemplateForm.get('filterByDevice').valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe( + value => this.deviceInactivityTemplateForm.get(value ? 'deviceProfiles' : 'devices').patchValue(null, {emitEvent: false}) + ); + this.entityActionTemplateForm = this.fb.group({ entityType: [], - status: this.fb.group({ - created: [false], - updated: [false], - deleted: [false] - }), - notificationTargetId: [], + created: [false], + updated: [false], + deleted: [false], + targets: [[], Validators.required], description: [''] }); @@ -166,12 +177,12 @@ export class RuleNotificationDialogComponent extends } onSeverityRemoved(severity: string): void { - const severities: string[] = this.alarmTemplateForm.get('alarmSeverityList').value; + const severities: string[] = this.alarmTemplateForm.get('alarmSeverities').value; const index = severities.indexOf(severity); if (index > -1) { severities.splice(index, 1); - this.alarmTemplateForm.get('alarmSeverityList').setValue(severities); - this.alarmTemplateForm.get('alarmSeverityList').markAsDirty(); + this.alarmTemplateForm.get('alarmSeverities').setValue(severities); + this.alarmTemplateForm.get('alarmSeverities').markAsDirty(); this.severitiesChipList.errorState = !severities.length; } } @@ -193,12 +204,12 @@ export class RuleNotificationDialogComponent extends private addSeverity(existingSeverity: string): boolean { if (existingSeverity) { - const displaySeverities: string[] = this.alarmTemplateForm.get('alarmSeverityList').value; + const displaySeverities: string[] = this.alarmTemplateForm.get('alarmSeverities').value; const index = displaySeverities.indexOf(existingSeverity); if (index === -1) { displaySeverities.push(existingSeverity); - this.alarmTemplateForm.get('alarmSeverityList').setValue(displaySeverities); - this.alarmTemplateForm.get('alarmSeverityList').markAsDirty(); + this.alarmTemplateForm.get('alarmSeverities').setValue(displaySeverities); + this.alarmTemplateForm.get('alarmSeverities').markAsDirty(); this.severitiesChipList.errorState = false; return true; } @@ -239,16 +250,16 @@ export class RuleNotificationDialogComponent extends } public alarmTypeList(): string[] { - return this.alarmTemplateForm.get('alarmTypeList').value; + return this.alarmTemplateForm.get('alarmTypes').value; } public removeAlarmType(type: string): void { - const types: string[] = this.alarmTemplateForm.get('alarmTypeList').value; + const types: string[] = this.alarmTemplateForm.get('alarmTypes').value; const index = types.indexOf(type); if (index >= 0) { types.splice(index, 1); - this.alarmTemplateForm.get('alarmTypeList').setValue(types); - this.alarmTemplateForm.get('alarmTypeList').markAsDirty(); + this.alarmTemplateForm.get('alarmTypes').setValue(types); + this.alarmTemplateForm.get('alarmTypes').markAsDirty(); } } @@ -256,12 +267,12 @@ export class RuleNotificationDialogComponent extends const input = event.input; const value = event.value; - const types: string[] = this.alarmTemplateForm.get('alarmTypeList').value; + const types: string[] = this.alarmTemplateForm.get('alarmTypes').value; if ((value || '').trim()) { types.push(value.trim()); - this.alarmTemplateForm.get('alarmTypeList').setValue(types); - this.alarmTemplateForm.get('alarmTypeList').markAsDirty(); + this.alarmTemplateForm.get('alarmTypes').setValue(types); + this.alarmTemplateForm.get('alarmTypes').markAsDirty(); } if (input) { @@ -307,22 +318,26 @@ export class RuleNotificationDialogComponent extends private add(): void { if (this.allValid()) { - const formValue: NotificationRule = this.ruleNotificationForm.value; - // if (formValue.configuration.deliveryMethodsTemplates.PUSH.enabled) { - // Object.assign(formValue.configuration.deliveryMethodsTemplates.PUSH, this.pushTemplateForm.value); - // } else { - // delete formValue.configuration.deliveryMethodsTemplates.PUSH; - // } - // if (formValue.configuration.deliveryMethodsTemplates.EMAIL.enabled) { - // Object.assign(formValue.configuration.deliveryMethodsTemplates.EMAIL, this.emailTemplateForm.value); - // } else { - // delete formValue.configuration.deliveryMethodsTemplates.EMAIL; - // } - // if (formValue.configuration.deliveryMethodsTemplates.SMS.enabled) { - // Object.assign(formValue.configuration.deliveryMethodsTemplates.SMS, this.smsTemplateForm.value); - // } else { - // delete formValue.configuration.deliveryMethodsTemplates.SMS; - // } + const formValue = this.ruleNotificationForm.value; + const triggerType = this.ruleNotificationForm.get('triggerType').value; + if (triggerType === TriggerType.ALARM) { + Object.assign(formValue.triggerConfig, this.alarmTemplateForm.value); + const parsedEscalationTable = {}; + this.alarmTemplateForm.get('escalationTable').value.forEach( + escalation => parsedEscalationTable[escalation.delayInSec] = escalation.targets + ); + formValue.recipientsConfig.escalationTable = parsedEscalationTable; + delete formValue.triggerConfig.escalationTable; + } else if (triggerType === TriggerType.DEVICE_INACTIVITY) { + Object.assign(formValue.triggerConfig, this.deviceInactivityTemplateForm.value); + delete formValue.triggerConfig.filterByDevice; + } else { + Object.assign(formValue.triggerConfig, this.entityActionTemplateForm.value); + } + if (triggerType === TriggerType.DEVICE_INACTIVITY || triggerType === TriggerType.ENTITY_ACTION) { + formValue.recipientsConfig.targets = this.entityActionTemplateForm.get('targets').value; + delete formValue.triggerConfig.trigger; + } this.notificationService.saveNotificationRule(deepTrim(formValue)).subscribe( (target) => this.dialogRef.close(target) ); diff --git a/ui-ngx/src/app/shared/models/notification.models.ts b/ui-ngx/src/app/shared/models/notification.models.ts index ad700f86f7..953a51e914 100644 --- a/ui-ngx/src/app/shared/models/notification.models.ts +++ b/ui-ngx/src/app/shared/models/notification.models.ts @@ -24,6 +24,8 @@ import { NotificationTargetId } from '@shared/models/id/notification-target-id'; import { NotificationTemplateId } from '@shared/models/id/notification-template-id'; import { EntityId } from '@shared/models/id/entity-id'; import { NotificationRuleId } from '@shared/models/id/notification-rule-id'; +import { AlarmSeverity, AlarmStatus } from '@shared/models/alarm.models'; +import { EntityType } from '@shared/models/entity-type.models'; export interface Notification { readonly id: NotificationId; @@ -100,18 +102,26 @@ export interface SlackConversation { export interface NotificationRule extends Omit, 'label'>{ tenantId: TenantId; templateId: NotificationTemplateId; - // deliveryMethods: Array; - configuration: NotificationRuleConfig; + triggerType: TriggerType; + triggerConfig: NotificationRuleTriggerConfig; + recipientConfig: NotificationRuleRecipientConfig; } -export interface NotificationRuleConfig { - initialNotificationTargetId: NotificationTargetId; - escalationConfig: NotificationEscalationConfig; - description?: string; +export interface NotificationRuleTriggerConfig { + alarmTypes?: Array; + alarmSeverities?: Array; + clearRule?: AlarmStatus; + devices?: Array; + devicesProfiles?: Array; + entityType?: EntityType; + created?: boolean; + updated?: boolean; + deleted?: boolean; } -export interface NotificationEscalationConfig { - escalations: Array; +export interface NotificationRuleRecipientConfig { + targets?: Array; + escalationTable?: {[key: string]: Array}; } export interface NonConfirmedNotificationEscalation { diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index c77fbc5b98..6b039e3e87 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2805,7 +2805,9 @@ "notify": "notify", "no-rule": "No rule configured", "device": "Device", + "devices": "Devices", "device-profile": "Device profile", + "device-profiles": "Device profiles", "filter-by": "Filter by", "entity-type": "Entity type", "created": "Created",