[fix] Threshold Rules search i18n error (#2692) (#2736)

Co-authored-by: keaifa <keaifafafa@gmail.com>
Co-authored-by: shown <yuluo08290126@gmail.com>
Co-authored-by: aias00 <rokkki@163.com>
This commit is contained in:
Keaifa 2024-09-25 09:21:47 +08:00 committed by GitHub
parent 7e3d009536
commit 108cc4db5a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 85 additions and 41 deletions

View File

@ -17,20 +17,12 @@
package org.apache.hertzbeat.alert.service.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Predicate;
import jakarta.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.alert.dao.AlertDefineBindDao;
import org.apache.hertzbeat.alert.dao.AlertDefineDao;
@ -56,6 +48,20 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Alarm definition management interface implementation
*/
@ -158,6 +164,18 @@ public class AlertDefineServiceImpl implements AlertDefineService {
@Override
public Page<AlertDefine> getAlertDefines(List<Long> defineIds, String search, Byte priority, String sort, String order, int pageIndex, int pageSize) {
// parse translation content list
ObjectMapper objectMapper = new ObjectMapper();
List<String> searchList = Collections.emptyList();
if (StringUtils.hasText(search)) {
try {
searchList = objectMapper.readValue(URLDecoder.decode(search, StandardCharsets.UTF_8), new TypeReference<>() {});
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Failed to parse search parameter", e);
}
}
List<String> finalSearchList = searchList;
// build search condition
Specification<AlertDefine> specification = (root, query, criteriaBuilder) -> {
List<Predicate> andList = new ArrayList<>();
if (defineIds != null && !defineIds.isEmpty()) {
@ -167,30 +185,21 @@ public class AlertDefineServiceImpl implements AlertDefineService {
}
andList.add(inPredicate);
}
if (StringUtils.hasText(search)) {
Predicate predicate = criteriaBuilder.or(
criteriaBuilder.like(
criteriaBuilder.lower(root.get("app")),
"%" + search.toLowerCase() + "%"
),
criteriaBuilder.like(
criteriaBuilder.lower(root.get("metric")),
"%" + search.toLowerCase() + "%"
),
criteriaBuilder.like(
criteriaBuilder.lower(root.get("field")),
"%" + search.toLowerCase() + "%"
),
criteriaBuilder.like(
criteriaBuilder.lower(root.get("expr")),
"%" + search.toLowerCase() + "%"
),
criteriaBuilder.like(
criteriaBuilder.lower(root.get("template")),
"%" + search.toLowerCase() + "%"
)
);
andList.add(predicate);
if (null != finalSearchList && !finalSearchList.isEmpty()) {
List<Predicate> searchPredicates = new ArrayList<>();
for (String searchContent : finalSearchList) {
searchContent = searchContent.toLowerCase();
Predicate predicate = criteriaBuilder.or(
criteriaBuilder.like(criteriaBuilder.lower(root.get("app")), "%" + searchContent + "%"),
criteriaBuilder.like(criteriaBuilder.lower(root.get("metric")), "%" + searchContent + "%"),
criteriaBuilder.like(criteriaBuilder.lower(root.get("field")), "%" + searchContent + "%"),
criteriaBuilder.like(criteriaBuilder.lower(root.get("expr")), "%" + searchContent + "%"),
criteriaBuilder.like(criteriaBuilder.lower(root.get("template")), "%" + searchContent + "%")
);
searchPredicates.add(predicate);
}
// all search keywords are connected with or
andList.add(criteriaBuilder.or(searchPredicates.toArray(new Predicate[0])));
}
if (priority != null) {
Predicate predicate = criteriaBuilder.equal(root.get("priority"), priority);

View File

@ -28,8 +28,8 @@ import { NzNotificationService } from 'ng-zorro-antd/notification';
import { NzTableQueryParams } from 'ng-zorro-antd/table';
import { TransferChange, TransferItem } from 'ng-zorro-antd/transfer';
import { NzUploadChangeParam } from 'ng-zorro-antd/upload';
import { zip } from 'rxjs';
import { finalize, map } from 'rxjs/operators';
import { EMPTY, zip } from 'rxjs';
import { catchError, finalize, map, switchMap, take, tap } from 'rxjs/operators';
import { AlertDefine } from '../../../pojo/AlertDefine';
import { AlertDefineBind } from '../../../pojo/AlertDefineBind';
@ -98,6 +98,8 @@ export class AlertSettingComponent implements OnInit {
return null;
};
qbFormCtrl: FormControl;
appMap = new Map<string, string>();
appEntries: Array<{ value: any; key: string }> = [];
ngOnInit(): void {
this.loadAlertDefineTable();
@ -131,6 +133,23 @@ export class AlertSettingComponent implements OnInit {
console.warn(error.msg);
}
);
// query i18n content
this.appDefineSvc
.getAppDefines(this.i18nSvc.defaultLang)
.pipe()
.subscribe(
message => {
if (message.code === 0) {
this.appMap = message.data;
this.appEntries = Object.entries(this.appMap).map(([key, value]) => ({ key, value }));
} else {
console.warn(message.msg);
}
},
error => {
console.warn(error.msg);
}
);
}
sync() {
@ -139,7 +158,22 @@ export class AlertSettingComponent implements OnInit {
loadAlertDefineTable() {
this.tableLoading = true;
let alertDefineInit$ = this.alertDefineSvc.getAlertDefines(this.search, this.pageIndex - 1, this.pageSize).subscribe(
const translationSearchList: string[] = [];
let trimSearch = '';
if (this.search !== undefined && this.search.trim() !== '') {
trimSearch = this.search.trim();
}
// Filter entries based on search input
this.appEntries.forEach(entry => {
if (trimSearch && entry.value.toLowerCase().includes(trimSearch.toLowerCase())) {
translationSearchList.push(entry.key);
}
});
// If no match found and search input exists, add search term to list
if (translationSearchList.length === 0 && trimSearch) {
translationSearchList.push(trimSearch);
}
let alertDefineInit$ = this.alertDefineSvc.getAlertDefines(translationSearchList, this.pageIndex - 1, this.pageSize).subscribe(
message => {
this.tableLoading = false;
this.checkedAll = false;

View File

@ -67,7 +67,7 @@ export class AlertDefineService {
return this.http.delete<Message<any>>(alert_defines_uri, options);
}
public getAlertDefines(search: string | undefined, pageIndex: number, pageSize: number): Observable<Message<Page<AlertDefine>>> {
public getAlertDefines(search: string[] | undefined, pageIndex: number, pageSize: number): Observable<Message<Page<AlertDefine>>> {
pageIndex = pageIndex ? pageIndex : 0;
pageSize = pageSize ? pageSize : 8;
// HttpParams is unmodifiable, so we need to save the return value of append/set
@ -78,8 +78,9 @@ export class AlertDefineService {
pageIndex: pageIndex,
pageSize: pageSize
});
if (search != undefined && search.trim() != '') {
httpParams = httpParams.append('search', search.trim());
if (search != undefined && search.length > 0) {
const searchJson = JSON.stringify(search);
httpParams = httpParams.append('search', encodeURIComponent(searchJson));
}
const options = { params: httpParams };
return this.http.get<Message<Page<AlertDefine>>>(alert_defines_uri, options);