From 076ccbba97084386f7e698e4c1ffde4c235fc9e1 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Tue, 27 Feb 2024 13:59:32 +0200 Subject: [PATCH 1/3] Open default alarm dashboard if none set for mobile notifications --- .../MobileAppNotificationChannel.java | 26 +++++++++++++------ .../AlarmAssignmentTriggerProcessor.java | 1 + .../trigger/AlarmCommentTriggerProcessor.java | 1 + .../rule/trigger/AlarmTriggerProcessor.java | 3 ++- .../server/common/data/alarm/Alarm.java | 10 +++++++ .../data/notification/NotificationType.java | 1 + .../info/AlarmAssignmentNotificationInfo.java | 7 +++++ .../info/AlarmCommentNotificationInfo.java | 7 +++++ .../info/AlarmNotificationInfo.java | 7 +++++ .../notification/info/NotificationInfo.java | 5 ++++ 10 files changed, 59 insertions(+), 9 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/notification/channels/MobileAppNotificationChannel.java b/application/src/main/java/org/thingsboard/server/service/notification/channels/MobileAppNotificationChannel.java index 3f2fcd40f5..8b90a8c69c 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/channels/MobileAppNotificationChannel.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/channels/MobileAppNotificationChannel.java @@ -61,14 +61,7 @@ public class MobileAppNotificationChannel implements NotificationChannel data = Optional.ofNullable(processedTemplate.getAdditionalConfig()) - .map(JacksonUtil::toFlatMap).orElseGet(HashMap::new); - Optional.ofNullable(ctx.getRequest().getInfo()) - .map(NotificationInfo::getStateEntityId) - .ifPresent(stateEntityId -> { - data.put("stateEntityId", stateEntityId.getId().toString()); - data.put("stateEntityType", stateEntityId.getEntityType().name()); - }); + Map data = getNotificationData(processedTemplate, ctx); for (String token : mobileSessions.keySet()) { try { firebaseService.sendMessage(ctx.getTenantId(), credentials, token, subject, body, data); @@ -87,6 +80,23 @@ public class MobileAppNotificationChannel implements NotificationChannel getNotificationData(MobileAppDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) { + Map data = Optional.ofNullable(processedTemplate.getAdditionalConfig()) + .map(JacksonUtil::toFlatMap).orElseGet(HashMap::new); + NotificationInfo info = ctx.getRequest().getInfo(); + Optional.ofNullable(info).map(NotificationInfo::getStateEntityId).ifPresent(stateEntityId -> { + data.put("stateEntityId", stateEntityId.getId().toString()); + data.put("stateEntityType", stateEntityId.getEntityType().name()); + if (!"true".equals(data.get("onClick.enabled")) && info.getDashboardId() != null) { + data.put("onClick.enabled", "true"); + data.put("onClick.linkType", "DASHBOARD"); + data.put("onClick.setEntityIdInState", "true"); + data.put("onClick.dashboardId", info.getDashboardId().toString()); + } + }); + return data; + } + @Override public void check(TenantId tenantId) throws Exception { NotificationSettings systemSettings = notificationSettingsService.findNotificationSettings(TenantId.SYS_TENANT_ID); diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java index 98981d0bc0..9cc7416e34 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmAssignmentTriggerProcessor.java @@ -65,6 +65,7 @@ public class AlarmAssignmentTriggerProcessor implements NotificationRuleTriggerP .alarmSeverity(alarmInfo.getSeverity()) .alarmStatus(alarmInfo.getStatus()) .alarmCustomerId(alarmInfo.getCustomerId()) + .dashboardId(alarmInfo.getDashboardId()) .build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java index a1199214ae..392f68dc9e 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmCommentTriggerProcessor.java @@ -76,6 +76,7 @@ public class AlarmCommentTriggerProcessor implements NotificationRuleTriggerProc .alarmSeverity(alarm.getSeverity()) .alarmStatus(alarm.getStatus()) .alarmCustomerId(alarm.getCustomerId()) + .dashboardId(alarm.getDashboardId()) .build(); } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmTriggerProcessor.java index 8022f6cbb3..99d58d40a9 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/AlarmTriggerProcessor.java @@ -22,11 +22,11 @@ import org.thingsboard.server.common.data.alarm.AlarmInfo; import org.thingsboard.server.common.data.alarm.AlarmStatusFilter; import org.thingsboard.server.common.data.notification.info.AlarmNotificationInfo; import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo; +import org.thingsboard.server.common.data.notification.rule.trigger.AlarmTrigger; import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmNotificationRuleTriggerConfig; import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmNotificationRuleTriggerConfig.AlarmAction; import org.thingsboard.server.common.data.notification.rule.trigger.config.AlarmNotificationRuleTriggerConfig.ClearRule; import org.thingsboard.server.common.data.notification.rule.trigger.config.NotificationRuleTriggerType; -import org.thingsboard.server.common.data.notification.rule.trigger.AlarmTrigger; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; import static org.thingsboard.server.common.data.util.CollectionsUtil.emptyOrContains; @@ -111,6 +111,7 @@ public class AlarmTriggerProcessor implements NotificationRuleTriggerProcessor implements HasName, HasTenantId, Ha } } + @JsonIgnore + public DashboardId getDashboardId() { + return Optional.ofNullable(getDetails()).map(details -> details.get("dashboardId")) + .filter(JsonNode::isTextual).map(id -> new DashboardId(UUID.fromString(id.asText()))).orElse(null); + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationType.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationType.java index cfc91d8fca..5a8fd87933 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationType.java @@ -31,4 +31,5 @@ public enum NotificationType { RATE_LIMITS, EDGE_CONNECTION, EDGE_COMMUNICATION_FAILURE + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmAssignmentNotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmAssignmentNotificationInfo.java index c2b12cc17c..13567405d8 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmAssignmentNotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmAssignmentNotificationInfo.java @@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.UserId; @@ -55,6 +56,7 @@ public class AlarmAssignmentNotificationInfo implements RuleOriginatedNotificati private AlarmSeverity alarmSeverity; private AlarmStatus alarmStatus; private CustomerId alarmCustomerId; + private DashboardId dashboardId; @Override public Map getTemplateData() { @@ -94,4 +96,9 @@ public class AlarmAssignmentNotificationInfo implements RuleOriginatedNotificati return alarmOriginator; } + @Override + public DashboardId getDashboardId() { + return dashboardId; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmCommentNotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmCommentNotificationInfo.java index aed023084f..d819b42c3c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmCommentNotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmCommentNotificationInfo.java @@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.EntityId; import java.util.Map; @@ -50,6 +51,7 @@ public class AlarmCommentNotificationInfo implements RuleOriginatedNotificationI private AlarmSeverity alarmSeverity; private AlarmStatus alarmStatus; private CustomerId alarmCustomerId; + private DashboardId dashboardId; @Override public Map getTemplateData() { @@ -80,4 +82,9 @@ public class AlarmCommentNotificationInfo implements RuleOriginatedNotificationI return alarmOriginator; } + @Override + public DashboardId getDashboardId() { + return dashboardId; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmNotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmNotificationInfo.java index 13b8c2e3ea..fb7fa478ea 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmNotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/AlarmNotificationInfo.java @@ -22,6 +22,7 @@ import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.EntityId; import java.util.Map; @@ -45,6 +46,7 @@ public class AlarmNotificationInfo implements RuleOriginatedNotificationInfo { private boolean acknowledged; private boolean cleared; private CustomerId alarmCustomerId; + private DashboardId dashboardId; @Override public Map getTemplateData() { @@ -70,4 +72,9 @@ public class AlarmNotificationInfo implements RuleOriginatedNotificationInfo { return alarmOriginator; } + @Override + public DashboardId getDashboardId() { + return dashboardId; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/NotificationInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/NotificationInfo.java index 14d2a876c0..50e3f05e6d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/NotificationInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/info/NotificationInfo.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.notification.info; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import org.thingsboard.server.common.data.id.DashboardId; import org.thingsboard.server.common.data.id.EntityId; import java.util.Map; @@ -33,4 +34,8 @@ public interface NotificationInfo { return null; } + default DashboardId getDashboardId() { + return null; + } + } From ff0ec47ae78b358e37068a1170f9d5b0362c3f32 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Tue, 27 Feb 2024 16:44:47 +0200 Subject: [PATCH 2/3] UI: Add hint for used default alarm dashboard in mobile push notification --- ...tion-action-button-configuration.component.html | 10 ++++++---- ...cation-action-button-configuration.component.ts | 3 +++ ...ification-template-configuration.component.html | 1 + ...otification-template-configuration.component.ts | 14 +++++++++++++- .../src/assets/locale/locale.constant-en_US.json | 1 + 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-action-button-configuration.component.html b/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-action-button-configuration.component.html index b195775d48..6ce736ead1 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-action-button-configuration.component.html +++ b/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-action-button-configuration.component.html @@ -20,10 +20,12 @@ [expanded]="actionButtonConfigForm.get('enabled').value"> - - {{ actionTitle }} - +
+ + {{ actionTitle }} + +
diff --git a/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-action-button-configuration.component.ts b/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-action-button-configuration.component.ts index af7e0a997b..e62d647694 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-action-button-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-action-button-configuration.component.ts @@ -52,6 +52,9 @@ export class NotificationActionButtonConfigurationComponent implements ControlVa @Input() actionTitle: string; + @Input() + sliderHint: string; + private hideButtonTextValue = false; get hideButtonText(): boolean { diff --git a/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.html b/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.html index 0a992618b9..54db7ece72 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.html +++ b/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.html @@ -124,6 +124,7 @@ diff --git a/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.ts b/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.ts index 1f54784d64..2d575f593f 100644 --- a/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/pages/notification/template/configuration/notification-template-configuration.component.ts @@ -36,6 +36,7 @@ import { takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; import { isDefinedAndNotNull } from '@core/utils'; import { coerceBoolean } from '@shared/decorators/coercion'; +import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'tb-template-configuration', @@ -96,7 +97,8 @@ export class NotificationTemplateConfigurationComponent implements OnDestroy, Co private propagateChange = (v: any) => { }; private readonly destroy$ = new Subject(); - constructor(private fb: FormBuilder) { + constructor(private fb: FormBuilder, + private translate: TranslateService) { this.templateConfigurationForm = this.buildForm(); this.templateConfigurationForm.valueChanges.pipe( takeUntil(this.destroy$) @@ -137,6 +139,16 @@ export class NotificationTemplateConfigurationComponent implements OnDestroy, Co }; } + get hotificationTapActionHint(): string { + switch (this.notificationType) { + case NotificationType.ALARM: + case NotificationType.ALARM_ASSIGNMENT: + case NotificationType.ALARM_COMMENT: + return this.translate.instant('notification.notification-tap-action-hint'); + } + return ''; + } + private updateDisabledForms(){ Object.values(NotificationDeliveryMethod).forEach((method) => { const form = this.templateConfigurationForm.get(method); 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 288db8c9d2..54a7ad15dc 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3349,6 +3349,7 @@ "notification": "Notification", "notification-center": "Notification center", "notification-tap-action": "Notification tap action", + "notification-tap-action-hint": "If not enabled, the default alarm dashboard will be used", "notify": "notify", "notify-again": "Notify again", "notify-alarm-action": { From db975f45682cdcf002a1a04e94625e9abf9aea82 Mon Sep 17 00:00:00 2001 From: ViacheslavKlimov Date: Wed, 28 Feb 2024 12:54:05 +0200 Subject: [PATCH 3/3] Add alarm info to mobile notification data --- .../channels/MobileAppNotificationChannel.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/org/thingsboard/server/service/notification/channels/MobileAppNotificationChannel.java b/application/src/main/java/org/thingsboard/server/service/notification/channels/MobileAppNotificationChannel.java index 8b90a8c69c..dc7f3f9d99 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/channels/MobileAppNotificationChannel.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/channels/MobileAppNotificationChannel.java @@ -84,7 +84,10 @@ public class MobileAppNotificationChannel implements NotificationChannel data = Optional.ofNullable(processedTemplate.getAdditionalConfig()) .map(JacksonUtil::toFlatMap).orElseGet(HashMap::new); NotificationInfo info = ctx.getRequest().getInfo(); - Optional.ofNullable(info).map(NotificationInfo::getStateEntityId).ifPresent(stateEntityId -> { + if (info == null) { + return data; + } + Optional.ofNullable(info.getStateEntityId()).ifPresent(stateEntityId -> { data.put("stateEntityId", stateEntityId.getId().toString()); data.put("stateEntityType", stateEntityId.getEntityType().name()); if (!"true".equals(data.get("onClick.enabled")) && info.getDashboardId() != null) { @@ -94,6 +97,16 @@ public class MobileAppNotificationChannel implements NotificationChannel { + data.put("info." + key, value); + }); + break; + } return data; }