diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java index 2c19803f5f..9b3316cbaf 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/rule/trigger/NotificationRuleTriggerConfig.java @@ -26,7 +26,7 @@ import java.io.Serializable; @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "triggerType") @JsonSubTypes({ @Type(value = AlarmNotificationRuleTriggerConfig.class, name = "ALARM"), - @Type(value = DeviceActivityNotificationRuleTriggerConfig.class, name = "DEVICE_INACTIVITY"), + @Type(value = DeviceActivityNotificationRuleTriggerConfig.class, name = "DEVICE_ACTIVITY"), @Type(value = EntityActionNotificationRuleTriggerConfig.class, name = "ENTITY_ACTION"), @Type(value = AlarmCommentNotificationRuleTriggerConfig.class, name = "ALARM_COMMENT"), @Type(value = RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig.class, name = "RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT"), 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 e1028b321a..7a91645e31 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 @@ -175,7 +175,6 @@ import { AssetProfileDialogComponent } from '@home/components/profile/asset-prof import { AssetProfileAutocompleteComponent } from '@home/components/profile/asset-profile-autocomplete.component'; import { MODULES_MAP } from '@shared/models/constants'; 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'; @@ -325,7 +324,6 @@ import { SendNotificationButtonComponent } from '@home/components/notification/s RateLimitsComponent, RateLimitsTextComponent, RateLimitsDetailsDialogComponent, - SlackConversationAutocompleteComponent, SendNotificationButtonComponent ], imports: [ @@ -466,7 +464,6 @@ import { SendNotificationButtonComponent } from '@home/components/notification/s RateLimitsComponent, RateLimitsTextComponent, RateLimitsDetailsDialogComponent, - SlackConversationAutocompleteComponent, SendNotificationButtonComponent ], providers: [ 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 53fbb095dd..4f1406c7f7 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 @@ -25,7 +25,7 @@ import { SentErrorDialogComponent } from '@home/pages/notification/sent/sent-err import { SentNotificationDialogComponent } from '@home/pages/notification/sent/sent-notification-dialog.componet'; import { RecipientNotificationDialogComponent -} from '@home/pages/notification/recipient/recipient-notification-dialog.componet'; +} from '@home/pages/notification/recipient/recipient-notification-dialog.component'; import { RecipientTableHeaderComponent } from '@home/pages/notification/recipient/recipient-table-header.component'; import { TemplateAutocompleteComponent } from '@home/pages/notification/template/template-autocomplete.component'; import { diff --git a/ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-notification-dialog.componet.scss b/ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-notification-dialog.component.scss similarity index 100% rename from ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-notification-dialog.componet.scss rename to ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-notification-dialog.component.scss diff --git a/ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-notification-dialog.componet.ts b/ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-notification-dialog.component.ts similarity index 94% rename from ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-notification-dialog.componet.ts rename to ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-notification-dialog.component.ts index 20e75ea195..c07d8beb75 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-notification-dialog.componet.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-notification-dialog.component.ts @@ -39,6 +39,7 @@ import { Authority } from '@shared/models/authority.enum'; import { AuthState } from '@core/auth/auth.models'; import { getCurrentAuthState } from '@core/auth/auth.selectors'; import { AuthUser } from '@shared/models/user.model'; +import { control } from 'leaflet'; export interface RecipientNotificationDialogData { target?: NotificationTarget; @@ -48,7 +49,7 @@ export interface RecipientNotificationDialogData { @Component({ selector: 'tb-target-notification-dialog', templateUrl: './recipient-notification-dialog.component.html', - styleUrls: ['recipient-notification-dialog.componet.scss'] + styleUrls: ['recipient-notification-dialog.component.scss'] }) export class RecipientNotificationDialogComponent extends DialogComponent implements OnDestroy { @@ -70,6 +71,7 @@ export class RecipientNotificationDialogComponent extends isAdd = true; private readonly destroy$ = new Subject(); + private userFilterFormControls: string[]; constructor(protected store: Store, protected router: Router, @@ -119,10 +121,15 @@ export class RecipientNotificationDialogComponent extends this.targetNotificationForm.get('configuration.description').enable({emitEvent: false}); }); + this.userFilterFormControls = Object.keys((this.targetNotificationForm.get('configuration.usersFilter') as FormGroup).controls) + .filter((controlName) => controlName !== 'type'); + this.targetNotificationForm.get('configuration.usersFilter.type').valueChanges.pipe( takeUntil(this.destroy$) ).subscribe((type: NotificationTargetConfigType) => { - this.targetNotificationForm.get('configuration.usersFilter').disable({emitEvent: false}); + this.userFilterFormControls.forEach( + controlName => this.targetNotificationForm.get(`configuration.usersFilter.${controlName}`).disable({emitEvent: false}) + ); switch (type) { case NotificationTargetConfigType.TENANT_ADMINISTRATORS: if (this.isSysAdmin()) { @@ -136,7 +143,6 @@ export class RecipientNotificationDialogComponent extends this.targetNotificationForm.get('configuration.usersFilter.customerId').enable({emitEvent: false}); break; } - this.targetNotificationForm.get('configuration.usersFilter.type').enable({emitEvent: false}); }); this.targetNotificationForm.get('configuration.usersFilter.filterByTenants').valueChanges.pipe( diff --git a/ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-table-config.resolver.ts b/ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-table-config.resolver.ts index 306b5e8ea8..05259e1edb 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-table-config.resolver.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/recipient/recipient-table-config.resolver.ts @@ -28,7 +28,7 @@ import { TranslateService } from '@ngx-translate/core'; import { RecipientNotificationDialogComponent, RecipientNotificationDialogData -} from '@home/pages/notification/recipient/recipient-notification-dialog.componet'; +} from '@home/pages/notification/recipient/recipient-notification-dialog.component'; import { MatDialog } from '@angular/material/dialog'; import { EntityAction } from '@home/models/entity/entity-component.models'; import { RecipientTableHeaderComponent } from '@home/pages/notification/recipient/recipient-table-header.component'; diff --git a/ui-ngx/src/app/modules/home/pages/notification/rule/escalation-form.component.ts b/ui-ngx/src/app/modules/home/pages/notification/rule/escalation-form.component.ts index b40c845174..089b234a24 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/rule/escalation-form.component.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/rule/escalation-form.component.ts @@ -37,7 +37,7 @@ import { takeUntil } from 'rxjs/operators'; import { RecipientNotificationDialogComponent, RecipientNotificationDialogData -} from '@home/pages/notification/recipient/recipient-notification-dialog.componet'; +} from '@home/pages/notification/recipient/recipient-notification-dialog.component'; import { MatDialog } from '@angular/material/dialog'; import { MatButton } from '@angular/material/button'; diff --git a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html index ff8d835ae9..b3cdb6daa2 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.html @@ -151,9 +151,9 @@ - - {{ 'notification.device-inactivity-trigger-settings' | translate }} + {{ 'notification.device-activity-trigger-settings' | translate }}
@@ -184,6 +184,17 @@ [entityType]="entityType.DEVICE_PROFILE"> + + notification.notify-on + + + {{ deviceEventTranslationMap.get(deviceEvent) | translate }} + + + + {{ 'notification.notify-on-required' | translate }} + +
@@ -202,11 +213,10 @@
notification.filter - - + +
notification.status {{ 'notification.created' | translate }} diff --git a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts index a39468db0f..4658ab62ef 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/rule/rule-notification-dialog.component.ts @@ -20,7 +20,7 @@ import { AlarmAssignmentAction, AlarmAssignmentActionTranslationMap, ComponentLifecycleEvent, - ComponentLifecycleEventTranslationMap, + ComponentLifecycleEventTranslationMap, DeviceEvent, DeviceEventTranslationMap, NotificationRule, NotificationTarget, TriggerType, @@ -52,7 +52,7 @@ import { TranslateService } from '@ngx-translate/core'; import { RecipientNotificationDialogComponent, RecipientNotificationDialogData -} from '@home/pages/notification/recipient/recipient-notification-dialog.componet'; +} from '@home/pages/notification/recipient/recipient-notification-dialog.component'; import { MatButton } from '@angular/material/button'; import { AuthState } from '@core/auth/auth.models'; import { getCurrentAuthState } from '@core/auth/auth.selectors'; @@ -110,6 +110,9 @@ export class RuleNotificationDialogComponent extends componentLifecycleEvents: ComponentLifecycleEvent[] = Object.values(ComponentLifecycleEvent); componentLifecycleEventTranslationMap = ComponentLifecycleEventTranslationMap; + deviceEvents: DeviceEvent[] = Object.values(DeviceEvent); + deviceEventTranslationMap = DeviceEventTranslationMap; + entityType = EntityType; entityTypes = Array.from(entityTypeTranslations.keys()).filter(type => !!this.entityType[type]); isAdd = true; @@ -197,7 +200,8 @@ export class RuleNotificationDialogComponent extends triggerConfig: this.fb.group({ filterByDevice: [true], devices: [null], - deviceProfiles: [{value: null, disabled: true}] + deviceProfiles: [{value: null, disabled: true}], + notifyOn: [[DeviceEvent.INACTIVE], Validators.required] }) }); @@ -215,7 +219,7 @@ export class RuleNotificationDialogComponent extends this.entityActionTemplateForm = this.fb.group({ triggerConfig: this.fb.group({ - entityType: [EntityType.DEVICE], + entityTypes: [[EntityType.DEVICE], Validators.required], created: [false], updated: [false], deleted: [false] @@ -262,7 +266,7 @@ export class RuleNotificationDialogComponent extends this.triggerTypeFormsMap = new Map([ [TriggerType.ALARM, this.alarmTemplateForm], [TriggerType.ALARM_COMMENT, this.alarmCommentTemplateForm], - [TriggerType.DEVICE_INACTIVITY, this.deviceInactivityTemplateForm], + [TriggerType.DEVICE_ACTIVITY, this.deviceInactivityTemplateForm], [TriggerType.ENTITY_ACTION, this.entityActionTemplateForm], [TriggerType.ALARM_ASSIGNMENT, this.alarmAssignmentTemplateForm], [TriggerType.RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT, this.ruleEngineEventsTemplateForm], @@ -283,7 +287,7 @@ export class RuleNotificationDialogComponent extends this.ruleNotificationForm.get('triggerType').updateValueAndValidity({onlySelf: true}); const currentForm = this.triggerTypeFormsMap.get(this.ruleNotification.triggerType); currentForm.patchValue(this.ruleNotification, {emitEvent: false}); - if (this.ruleNotification.triggerType === TriggerType.DEVICE_INACTIVITY) { + if (this.ruleNotification.triggerType === TriggerType.DEVICE_ACTIVITY) { this.deviceInactivityTemplateForm.get('triggerConfig.filterByDevice') .patchValue(!!this.ruleNotification.triggerConfig.devices, {onlySelf: true}); } @@ -329,7 +333,7 @@ export class RuleNotificationDialogComponent extends const triggerType: TriggerType = this.ruleNotificationForm.get('triggerType').value; const currentForm = this.triggerTypeFormsMap.get(triggerType); Object.assign(formValue, currentForm.value); - if (triggerType === TriggerType.DEVICE_INACTIVITY) { + if (triggerType === TriggerType.DEVICE_ACTIVITY) { delete formValue.triggerConfig.filterByDevice; } formValue.recipientsConfig.triggerType = triggerType; diff --git a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.componet.ts b/ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.componet.ts index 7cdb791037..47950bd6c4 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.componet.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/sent/sent-notification-dialog.componet.ts @@ -41,7 +41,7 @@ import { getCurrentTime } from '@shared/models/time/time.models'; import { RecipientNotificationDialogComponent, RecipientNotificationDialogData -} from '@home/pages/notification/recipient/recipient-notification-dialog.componet'; +} from '@home/pages/notification/recipient/recipient-notification-dialog.component'; import { MatButton } from '@angular/material/button'; import { TemplateConfiguration } from '@home/pages/notification/template/template-configuration'; diff --git a/ui-ngx/src/app/modules/home/pages/notification/template/template-autocomplete.component.ts b/ui-ngx/src/app/modules/home/pages/notification/template/template-autocomplete.component.ts index 9a3e6037a1..e273385da1 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/template/template-autocomplete.component.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/template/template-autocomplete.component.ts @@ -133,7 +133,6 @@ export class TemplateAutocompleteComponent implements ControlValueAccessor, OnIn } }), map(value => value ? (typeof value === 'string' ? value : value.name) : ''), - distinctUntilChanged(), switchMap(name => this.fetchTemplate(name)), share() ); diff --git a/ui-ngx/src/app/modules/home/components/notification/slack-conversation-autocomplete.component.html b/ui-ngx/src/app/shared/components/slack-conversation-autocomplete.component.html similarity index 100% rename from ui-ngx/src/app/modules/home/components/notification/slack-conversation-autocomplete.component.html rename to ui-ngx/src/app/shared/components/slack-conversation-autocomplete.component.html diff --git a/ui-ngx/src/app/modules/home/components/notification/slack-conversation-autocomplete.component.scss b/ui-ngx/src/app/shared/components/slack-conversation-autocomplete.component.scss similarity index 100% rename from ui-ngx/src/app/modules/home/components/notification/slack-conversation-autocomplete.component.scss rename to ui-ngx/src/app/shared/components/slack-conversation-autocomplete.component.scss diff --git a/ui-ngx/src/app/modules/home/components/notification/slack-conversation-autocomplete.component.ts b/ui-ngx/src/app/shared/components/slack-conversation-autocomplete.component.ts similarity index 100% rename from ui-ngx/src/app/modules/home/components/notification/slack-conversation-autocomplete.component.ts rename to ui-ngx/src/app/shared/components/slack-conversation-autocomplete.component.ts diff --git a/ui-ngx/src/app/shared/models/notification.models.ts b/ui-ngx/src/app/shared/models/notification.models.ts index 14342fabf4..31a3c03cc1 100644 --- a/ui-ngx/src/app/shared/models/notification.models.ts +++ b/ui-ngx/src/app/shared/models/notification.models.ts @@ -203,6 +203,16 @@ export const AlarmAssignmentActionTranslationMap = new Map([ + [DeviceEvent.ACTIVE, 'notification.active'], + [DeviceEvent.INACTIVE, 'notification.inactive'] +]); + export interface NotificationRuleRecipientConfig { targets?: Array; escalationTable?: {[key: number]: Array}; @@ -415,7 +425,7 @@ export const NotificationTargetConfigTypeInfoMap = new Map([ [NotificationType.ALARM, 'warning'], - [NotificationType.DEVICE_INACTIVITY, 'phonelink_off'], + [NotificationType.DEVICE_ACTIVITY, 'phonelink_off'], [NotificationType.ENTITY_ACTION, 'devices'], [NotificationType.ALARM_COMMENT, 'comment'], [NotificationType.ALARM_ASSIGNMENT, 'assignment_turned_in'], @@ -471,10 +481,10 @@ export const NotificationTemplateTypeTranslateMap = new Map([ [TriggerType.ALARM, 'notification.trigger.alarm'], - [TriggerType.DEVICE_INACTIVITY, 'notification.trigger.device-inactivity'], + [TriggerType.DEVICE_ACTIVITY, 'notification.trigger.device-activity'], [TriggerType.ENTITY_ACTION, 'notification.trigger.entity-action'], [TriggerType.ALARM_COMMENT, 'notification.trigger.alarm-comment'], [TriggerType.ALARM_ASSIGNMENT, 'notification.trigger.alarm-assignment'], diff --git a/ui-ngx/src/app/shared/shared.module.ts b/ui-ngx/src/app/shared/shared.module.ts index 6108fdbeaf..3ebbac3faa 100644 --- a/ui-ngx/src/app/shared/shared.module.ts +++ b/ui-ngx/src/app/shared/shared.module.ts @@ -173,6 +173,7 @@ import { CustomDateAdapter } from '@shared/adapter/custom-datatime-adapter'; import { CustomPaginatorIntl } from '@shared/services/custom-paginator-intl'; import { TbScriptLangComponent } from '@shared/components/script-lang.component'; import { NotificationComponent } from '@shared/components/notification/notification.component'; +import { SlackConversationAutocompleteComponent } from '@shared/components/slack-conversation-autocomplete.component'; import { DateAgoPipe } from '@shared/pipe/date-ago.pipe'; export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) { @@ -323,6 +324,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) PhoneInputComponent, TbScriptLangComponent, NotificationComponent, + SlackConversationAutocompleteComponent, DateAgoPipe ], imports: [ @@ -535,6 +537,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) PhoneInputComponent, TbScriptLangComponent, NotificationComponent, + SlackConversationAutocompleteComponent, DateAgoPipe ] }) 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 8d522acf3e..a0f95cf0e6 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2729,6 +2729,7 @@ "notification": { "action-button": "Action button", "action-type": "Action type", + "active": "Active", "add-notification-recipients-group": "Add notification recipients group", "add-notification-template": "Add notification template", "add-recipient": "Add recipient", @@ -2791,7 +2792,7 @@ }, "delivery-methods": "Delivery methods", "description": "Description", - "device-inactivity-trigger-settings": "Device inactive trigger settings", + "device-activity-trigger-settings": "Device active trigger settings", "device-list-rule-hint": "If the field is empty, the trigger will be applied to all devices", "device-profiles-list-rule-hint": "If the field is empty, the trigger will be applied to all device profiles", "edit-notification-recipients-group": "Edit notification recipients group", @@ -2806,6 +2807,7 @@ "fails": "Fails", "filter": "Filter", "first-recipient": "First recipient", + "inactive": "Inactive", "inbox": "Inbox", "input-field-support-templatization": "Input field support templatization.", "input-fields-support-templatization": "Input fields support templatization.", @@ -2919,7 +2921,7 @@ "alarm": "Alarm", "alarm-assignment": "Alarm assignment", "alarm-comment": "Alarm comment", - "device-inactivity": "Device inactivity", + "device-activity": "Device activity", "entities-limit": "Entities limit", "entity-action": "Entity action", "general": "General", @@ -2935,7 +2937,7 @@ "alarm": "Alarm", "alarm-assignment": "Alarm assignment", "alarm-comment": "Alarm comment", - "device-inactivity": "Device inactivity", + "device-activity": "Device activity", "entities-limit": "Entities limit", "entity-action": "Entity action", "rule-engine-lifecycle-event": "Rule engine lifecycle event",