Browse Source

Merge pull request #14336 from dashevchenko/alarmCommentTranslation

Added system alarm comments localization
pull/14369/head
Viacheslav Klimov 7 months ago
committed by GitHub
parent
commit
f8a8df29ba
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 9
      application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmCommentService.java
  2. 50
      application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java
  3. 9
      application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java
  4. 13
      application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java
  5. 36
      common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCommentSubType.java
  6. 19
      ui-ngx/src/app/modules/home/components/alarm/alarm-comment.component.ts
  7. 15
      ui-ngx/src/app/shared/models/alarm.models.ts
  8. 11
      ui-ngx/src/assets/locale/locale.constant-en_US.json

9
application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmCommentService.java

@ -30,6 +30,8 @@ import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.dao.alarm.AlarmCommentService;
import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
import static org.thingsboard.server.common.data.alarm.AlarmCommentSubType.COMMENT_DELETED;
@Service
@AllArgsConstructor
public class DefaultTbAlarmCommentService extends AbstractTbEntityService implements TbAlarmCommentService {
@ -59,9 +61,10 @@ public class DefaultTbAlarmCommentService extends AbstractTbEntityService implem
if (alarmComment.getType() == AlarmCommentType.OTHER) {
alarmComment.setType(AlarmCommentType.SYSTEM);
alarmComment.setUserId(null);
alarmComment.setComment(JacksonUtil.newObjectNode().put("text",
String.format("User %s deleted his comment",
(user.getFirstName() == null || user.getLastName() == null) ? user.getName() : user.getFirstName() + " " + user.getLastName())));
alarmComment.setComment(JacksonUtil.newObjectNode()
.put("text", String.format(COMMENT_DELETED.getText(), user.getTitle()))
.put("subtype", COMMENT_DELETED.name())
.put("userName", user.getTitle()));
AlarmComment savedAlarmComment = checkNotNull(alarmCommentService.saveAlarmComment(alarm.getTenantId(), alarmComment));
logEntityActionService.logEntityAction(alarm.getTenantId(), alarm.getId(), alarm, alarm.getCustomerId(), ActionType.DELETED_COMMENT, user, savedAlarmComment);
} else {

50
application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java

@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmApiCallResult;
import org.thingsboard.server.common.data.alarm.AlarmAssignee;
import org.thingsboard.server.common.data.alarm.AlarmComment;
import org.thingsboard.server.common.data.alarm.AlarmCommentSubType;
import org.thingsboard.server.common.data.alarm.AlarmCommentType;
import org.thingsboard.server.common.data.alarm.AlarmCreateOrUpdateActiveRequest;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
@ -39,9 +40,17 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.service.entitiy.AbstractTbEntityService;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import static org.thingsboard.server.common.data.alarm.AlarmCommentSubType.ACKED_BY_USER;
import static org.thingsboard.server.common.data.alarm.AlarmCommentSubType.ASSIGNED_TO_USER;
import static org.thingsboard.server.common.data.alarm.AlarmCommentSubType.CLEARED_BY_USER;
import static org.thingsboard.server.common.data.alarm.AlarmCommentSubType.UNASSIGNED_BY_USER;
import static org.thingsboard.server.common.data.alarm.AlarmCommentSubType.UNASSIGNED_FROM_DELETED_USER;
@Service
@AllArgsConstructor
@Slf4j
@ -102,8 +111,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
}
AlarmInfo alarmInfo = result.getAlarm();
if (result.isModified()) {
String systemComment = String.format("Alarm was acknowledged by user %s", user.getTitle());
addSystemAlarmComment(alarmInfo, user, "ACK", systemComment);
addSystemAlarmComment(alarmInfo, user, ACKED_BY_USER,"userName", user.getTitle());
logEntityActionService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo,
alarmInfo.getCustomerId(), ActionType.ALARM_ACK, user);
} else {
@ -125,8 +133,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
}
AlarmInfo alarmInfo = result.getAlarm();
if (result.isCleared()) {
String systemComment = String.format("Alarm was cleared by user %s", user.getTitle());
addSystemAlarmComment(alarmInfo, user, "CLEAR", systemComment);
addSystemAlarmComment(alarmInfo, user, CLEARED_BY_USER, "userName", user.getTitle());
logEntityActionService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo,
alarmInfo.getCustomerId(), ActionType.ALARM_CLEAR, user);
} else {
@ -144,8 +151,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
AlarmInfo alarmInfo = result.getAlarm();
if (result.isModified()) {
AlarmAssignee assignee = alarmInfo.getAssignee();
String systemComment = String.format("Alarm was assigned by user %s to user %s", user.getTitle(), assignee.getTitle());
addSystemAlarmComment(alarmInfo, user, "ASSIGN", systemComment, assignee.getId());
addSystemAlarmComment(alarmInfo, user, ASSIGNED_TO_USER, "userName", user.getTitle(), "assigneeName", assignee.getTitle());
logEntityActionService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo,
alarmInfo.getCustomerId(), ActionType.ALARM_ASSIGNED, user);
} else {
@ -162,8 +168,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
}
AlarmInfo alarmInfo = result.getAlarm();
if (result.isModified()) {
String systemComment = String.format("Alarm was unassigned by user %s", user.getTitle());
addSystemAlarmComment(alarmInfo, user, "ASSIGN", systemComment);
addSystemAlarmComment(alarmInfo, user, UNASSIGNED_BY_USER, "userName", user.getTitle());
logEntityActionService.logEntityAction(alarm.getTenantId(), alarm.getOriginator(), alarmInfo,
alarmInfo.getCustomerId(), ActionType.ALARM_UNASSIGNED, user);
} else {
@ -182,8 +187,7 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
continue;
}
if (result.isModified()) {
String comment = String.format("Alarm was unassigned because user %s - was deleted", userTitle);
addSystemAlarmComment(result.getAlarm(), null, "ASSIGN", comment);
addSystemAlarmComment(result.getAlarm(), null, UNASSIGNED_FROM_DELETED_USER, "userName", userTitle);
logEntityActionService.logEntityAction(result.getAlarm().getTenantId(), result.getAlarm().getOriginator(), result.getAlarm(), result.getAlarm().getCustomerId(), ActionType.ALARM_UNASSIGNED, null);
}
}
@ -214,20 +218,24 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb
return ts > 0 ? ts : System.currentTimeMillis();
}
private void addSystemAlarmComment(Alarm alarm, User user, String subType, String commentText) {
addSystemAlarmComment(alarm, user, subType, commentText, null);
private void addSystemAlarmComment(Alarm alarm, User user, AlarmCommentSubType subType, String param, String value) {
Map<String, String> params = new LinkedHashMap<>(1);
params.put(param, value);
addSystemAlarmComment(alarm, user, subType, params);
}
private void addSystemAlarmComment(Alarm alarm, User user, AlarmCommentSubType subType, String param, String value, String param2, String value2) {
Map<String, String> params = new LinkedHashMap<>(2);
params.put(param, value);
params.put(param2, value2);
addSystemAlarmComment(alarm, user, subType, params);
}
private void addSystemAlarmComment(Alarm alarm, User user, String subType, String commentText, UserId assigneeId) {
private void addSystemAlarmComment(Alarm alarm, User user, AlarmCommentSubType subType, Map<String, String> params) {
ObjectNode commentNode = JacksonUtil.newObjectNode();
commentNode.put("text", commentText)
.put("subtype", subType);
if (user != null) {
commentNode.put("userId", user.getId().getId().toString());
}
if (assigneeId != null) {
commentNode.put("assigneeId", assigneeId.getId().toString());
}
commentNode.put("text", String.format(subType.getText(), params.values().toArray()))
.put("subtype", subType.name());
params.forEach(commentNode::put);
AlarmComment alarmComment = AlarmComment.builder()
.alarmId(alarm.getId())
.type(AlarmCommentType.SYSTEM)

9
application/src/main/java/org/thingsboard/server/service/telemetry/DefaultAlarmSubscriptionService.java

@ -61,6 +61,8 @@ import org.thingsboard.server.service.subscription.TbSubscriptionUtils;
import java.util.Collection;
import static org.thingsboard.server.common.data.alarm.AlarmCommentSubType.SEVERITY_CHANGED;
/**
* Created by ashvayka on 27.03.18.
*/
@ -251,8 +253,11 @@ public class DefaultAlarmSubscriptionService extends AbstractSubscriptionService
AlarmComment.AlarmCommentBuilder alarmComment = AlarmComment.builder()
.alarmId(alarm.getId())
.type(AlarmCommentType.SYSTEM)
.comment(JacksonUtil.newObjectNode().put("text",
String.format("Alarm severity was updated from %s to %s", result.getOldSeverity(), alarm.getSeverity())));
.comment(JacksonUtil.newObjectNode()
.put("text", String.format(SEVERITY_CHANGED.getText(), result.getOldSeverity(), alarm.getSeverity()))
.put("subtype", SEVERITY_CHANGED.name())
.put("oldSeverity", result.getOldSeverity().name())
.put("newSeverity", alarm.getSeverity().name()));
if (request != null && request.getUserId() != null) {
alarmComment.userId(request.getUserId());
}

13
application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java

@ -48,6 +48,7 @@ import java.util.List;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.thingsboard.server.common.data.alarm.AlarmCommentSubType.COMMENT_DELETED;
@Slf4j
@ContextConfiguration(classes = {AlarmCommentControllerTest.Config.class})
@ -207,8 +208,10 @@ public class AlarmCommentControllerTest extends AbstractControllerTest {
AlarmComment expectedAlarmComment = AlarmComment.builder()
.alarmId(alarm.getId())
.type(AlarmCommentType.SYSTEM)
.comment(JacksonUtil.newObjectNode().put("text", String.format("User %s deleted his comment",
CUSTOMER_USER_EMAIL)))
.comment(JacksonUtil.newObjectNode()
.put("text", String.format(COMMENT_DELETED.getText(), CUSTOMER_USER_EMAIL))
.put("subtype", COMMENT_DELETED.name())
.put("userName", CUSTOMER_USER_EMAIL))
.build();
testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment);
}
@ -226,8 +229,10 @@ public class AlarmCommentControllerTest extends AbstractControllerTest {
AlarmComment expectedAlarmComment = AlarmComment.builder()
.alarmId(alarm.getId())
.type(AlarmCommentType.SYSTEM)
.comment(JacksonUtil.newObjectNode().put("text", String.format("User %s deleted his comment",
TENANT_ADMIN_EMAIL)))
.comment(JacksonUtil.newObjectNode()
.put("text", String.format(COMMENT_DELETED.getText(), TENANT_ADMIN_EMAIL))
.put("subtype", COMMENT_DELETED.name())
.put("userName", TENANT_ADMIN_EMAIL))
.build();
testLogEntityActionEntityEqClass(alarm, alarm.getId(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED_COMMENT, 1, expectedAlarmComment);
}

36
common/data/src/main/java/org/thingsboard/server/common/data/alarm/AlarmCommentSubType.java

@ -0,0 +1,36 @@
/**
* Copyright © 2016-2025 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.
*/
package org.thingsboard.server.common.data.alarm;
import lombok.Getter;
public enum AlarmCommentSubType {
ACKED_BY_USER("Alarm was acknowledged by user %s"),
CLEARED_BY_USER("Alarm was cleared by user %s"),
ASSIGNED_TO_USER("Alarm was assigned by user %s to user %s"),
UNASSIGNED_BY_USER("Alarm was unassigned by user %s"),
UNASSIGNED_FROM_DELETED_USER("Alarm was unassigned because user %s - was deleted"),
COMMENT_DELETED("User %s deleted his comment"),
SEVERITY_CHANGED("Alarm severity was updated from %s to %s");
@Getter
private final String text;
AlarmCommentSubType(String text) {
this.text = text;
}
}

19
ui-ngx/src/app/modules/home/components/alarm/alarm-comment.component.ts

@ -27,7 +27,13 @@ import { Direction, SortOrder } from '@shared/models/page/sort-order';
import { MAX_SAFE_PAGE_SIZE, PageLink } from '@shared/models/page/page-link';
import { DateAgoPipe } from '@shared/pipe/date-ago.pipe';
import { map } from 'rxjs/operators';
import { AlarmComment, AlarmCommentType, getUserDisplayName } from '@shared/models/alarm.models';
import {
AlarmComment,
AlarmCommentInfo,
AlarmCommentType,
AlarmMessage,
getUserDisplayName
} from '@shared/models/alarm.models';
import { UtilsService } from '@core/services/utils.service';
import { EntityType } from '@shared/models/entity-type.models';
import { DatePipe } from '@angular/common';
@ -121,7 +127,7 @@ export class AlarmCommentComponent implements OnInit {
const displayDataElement = {} as AlarmCommentsDisplayData;
displayDataElement.createdTime = this.datePipe.transform(alarmComment.createdTime, 'yyyy-MM-dd HH:mm:ss');
displayDataElement.createdDateAgo = this.dateAgoPipe.transform(alarmComment.createdTime);
displayDataElement.commentText = alarmComment.comment.text;
displayDataElement.commentText = this.parseSystemComment(alarmComment);
displayDataElement.isSystemComment = alarmComment.type === AlarmCommentType.SYSTEM;
if (alarmComment.type === AlarmCommentType.OTHER) {
displayDataElement.commentId = alarmComment.id.id;
@ -144,6 +150,15 @@ export class AlarmCommentComponent implements OnInit {
);
}
private parseSystemComment(alarm: AlarmCommentInfo): string {
const subTypeKey = alarm.comment?.subtype;
if (subTypeKey && AlarmMessage[subTypeKey]) {
const translationKey = AlarmMessage[subTypeKey];
return this.translate.instant(translationKey, alarm.comment);
}
return alarm.comment.text;
}
changeSortDirection() {
const currentDirection = this.alarmCommentSortOrder.direction;
this.alarmCommentSortOrder.direction = currentDirection === Direction.DESC ? Direction.ASC : Direction.DESC;

15
ui-ngx/src/app/shared/models/alarm.models.ts

@ -120,12 +120,27 @@ export enum AlarmCommentType {
OTHER = 'OTHER'
}
export enum AlarmMessage {
ACKED_BY_USER = "alarm.system-comments.acked-by-user",
CLEARED_BY_USER = "alarm.system-comments.cleared-by-user",
ASSIGNED_TO_USER = "alarm.system-comments.assigned-to-user",
UNASSIGNED_BY_USER = "alarm.system-comments.unassigned-to-user",
UNASSIGNED_FROM_DELETED_USER = "alarm.system-comments.unassigned-from-deleted-user",
COMMENT_DELETED = "alarm.system-comments.comment-deleted",
SEVERITY_CHANGED = "alarm.system-comments.severity-changed",
}
export interface AlarmComment extends BaseData<AlarmCommentId> {
alarmId: AlarmId;
userId?: UserId;
type: AlarmCommentType;
comment: {
text: string;
subtype?: keyof typeof AlarmMessage;
userName?: string;
assigneeName?: string;
oldSeverity?: AlarmSeverity;
newSeverity?: AlarmSeverity;
edited?: boolean;
editedOn?: number;
};

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

@ -657,7 +657,16 @@
"alarm-type": "Alarm type",
"enter-alarm-type": "Enter alarm type",
"no-alarm-types-matching": "No alarm types matching '{{entitySubtype}}' were found.",
"alarm-type-list-empty": "No alarm types selected."
"alarm-type-list-empty": "No alarm types selected.",
"system-comments": {
"acked-by-user": "Alarm was acknowledged by user {{userName}}",
"cleared-by-user": "Alarm was cleared by user {{userName}}",
"assigned-to-user": "Alarm was assigned by user {{userName}} to user {{assigneeName}}",
"unassigned-to-user": "Alarm was unassigned by user {{userName}}",
"unassigned-from-deleted-user": "Alarm was unassigned because user {{userName}} - was deleted",
"comment-deleted": "User {{userName}} deleted his comment",
"severity-changed": "Alarm severity was updated from {{oldSeverity}} to {{newSeverity}}"
}
},
"alarm-activity": {
"add": "Add a comment...",

Loading…
Cancel
Save