This is an automated email from the ASF dual-hosted git repository.

zhaoqingran pushed a commit to branch bulletin
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git


The following commit(s) were added to refs/heads/bulletin by this push:
     new a0452f806 ```feat(bulletin): i18n support and table display adjustments
a0452f806 is described below

commit a0452f806b5adbd15ceb101024f03efaed9c30b6
Author: zqr10159 <[email protected]>
AuthorDate: Thu Aug 22 15:51:01 2024 +0800

    ```feat(bulletin): i18n support and table display adjustments
    
    - Refactor bulletin component HTML for i18n support and update table 
display logic.
    - Replace hardcoded strings with i18n tokens for better localization 
support.
    - Modify table structure to dynamically render rows and columns based on 
fetched data.
    - Improve readability and maintainability of the codebase by removing 
redundant comments  and simplifying complex structures.
    
    BREAKING CHANGE: Changes to the table rendering logic might affect existing 
dashboard
    layouts. Ensure to verify the display of bulletin tables after update.
    ```
---
 .../common/entity/manager/bulletin/Bulletin.java   | 10 +--
 .../entity/manager/bulletin/BulletinDto.java       |  7 +-
 .../manager/bulletin/BulletinMetricsData.java      | 77 +++++++++++++-----
 .../org/apache/hertzbeat/common/util/JsonUtil.java |  4 +-
 .../manager/controller/BulletinController.java     | 34 ++------
 .../apache/hertzbeat/manager/dao/BulletinDao.java  | 32 ++++----
 .../hertzbeat/manager/service/BulletinService.java |  6 +-
 .../manager/service/impl/BulletinServiceImpl.java  | 21 +----
 web-app/src/app/pojo/BulletinDefine.ts             |  1 -
 .../app/routes/bulletin/bulletin.component.html    | 90 +++++++++++-----------
 .../src/app/routes/bulletin/bulletin.component.ts  | 27 +++++--
 web-app/src/assets/i18n/en-US.json                 | 12 +++
 web-app/src/assets/i18n/zh-CN.json                 | 10 +--
 web-app/src/assets/i18n/zh-TW.json                 | 12 +++
 14 files changed, 177 insertions(+), 166 deletions(-)

diff --git 
a/common/src/main/java/org/apache/hertzbeat/common/entity/manager/bulletin/Bulletin.java
 
b/common/src/main/java/org/apache/hertzbeat/common/entity/manager/bulletin/Bulletin.java
index 2b004f06b..a500a6320 100644
--- 
a/common/src/main/java/org/apache/hertzbeat/common/entity/manager/bulletin/Bulletin.java
+++ 
b/common/src/main/java/org/apache/hertzbeat/common/entity/manager/bulletin/Bulletin.java
@@ -17,15 +17,12 @@
 
 package org.apache.hertzbeat.common.entity.manager.bulletin;
 
-import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_ONLY;
 import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_WRITE;
 import io.swagger.v3.oas.annotations.media.Schema;
 import jakarta.persistence.Column;
 import jakarta.persistence.Convert;
 import jakarta.persistence.Entity;
 import jakarta.persistence.EntityListeners;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
 import jakarta.persistence.Id;
 import jakarta.persistence.Table;
 import java.time.LocalDateTime;
@@ -35,7 +32,6 @@ import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import 
org.apache.hertzbeat.common.entity.manager.JsonLongListAttributeConverter;
-import 
org.apache.hertzbeat.common.entity.manager.JsonStringListAttributeConverter;
 import 
org.apache.hertzbeat.common.entity.manager.JsonTagListAttributeConverter;
 import org.apache.hertzbeat.common.entity.manager.TagItem;
 import org.springframework.data.annotation.CreatedBy;
@@ -65,17 +61,13 @@ public class Bulletin {
     private String name;
 
     @Schema(description = "Monitor IDs", example = "1")
-    @Column(name = "monitor_ids")
+    @Column(name = "monitor_ids", length = 5000)
     @Convert(converter = JsonLongListAttributeConverter.class)
     private List<Long> monitorIds;
 
     @Schema(description = "Monitor Type eg: jvm, tomcat", example = "jvm", 
accessMode = READ_WRITE)
     private String app;
 
-    @Schema(description = "Monitor Metrics", example = "cpu, memory")
-    @Column(length = 4096)
-    @Convert(converter = JsonStringListAttributeConverter.class)
-    private List<String> metrics;
 
     @Schema(description = "Monitor Fields")
     @Column(length = 4096, columnDefinition = "json")
diff --git 
a/common/src/main/java/org/apache/hertzbeat/common/entity/manager/bulletin/BulletinDto.java
 
b/common/src/main/java/org/apache/hertzbeat/common/entity/manager/bulletin/BulletinDto.java
index f8e91b4ab..f077fd726 100644
--- 
a/common/src/main/java/org/apache/hertzbeat/common/entity/manager/bulletin/BulletinDto.java
+++ 
b/common/src/main/java/org/apache/hertzbeat/common/entity/manager/bulletin/BulletinDto.java
@@ -22,6 +22,9 @@ import java.util.List;
 import java.util.Map;
 import lombok.Data;
 
+/**
+ * Bulletin DTO
+ */
 @Data
 public class BulletinDto {
 
@@ -35,10 +38,6 @@ public class BulletinDto {
      */
     private String app;
 
-    /**
-     * Monitor metrics
-     */
-    private List<String> metrics;
 
     /**
      * Monitor fields
diff --git 
a/common/src/main/java/org/apache/hertzbeat/common/entity/manager/bulletin/BulletinMetricsData.java
 
b/common/src/main/java/org/apache/hertzbeat/common/entity/manager/bulletin/BulletinMetricsData.java
index a3b12217c..33f93a200 100644
--- 
a/common/src/main/java/org/apache/hertzbeat/common/entity/manager/bulletin/BulletinMetricsData.java
+++ 
b/common/src/main/java/org/apache/hertzbeat/common/entity/manager/bulletin/BulletinMetricsData.java
@@ -1,21 +1,18 @@
 /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
  *
- *  * Licensed to the Apache Software Foundation (ASF) under one or more
- *  * contributor license agreements.  See the NOTICE file distributed with
- *  * this work for additional information regarding copyright ownership.
- *  * The ASF licenses this file to You 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.
- *
+ *     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.apache.hertzbeat.common.entity.manager.bulletin;
@@ -37,36 +34,55 @@ import lombok.NoArgsConstructor;
 @Schema(description = "Bulletin Metrics Data")
 public class BulletinMetricsData {
 
+    /**
+     * Bulletin Name
+     */
     @Schema(title = "Bulletin Name")
     private String name;
 
-    @Schema(title = "Bulletin Column")
-    private List<String> column;
-
-    @Schema(title = "Bulletin Fields")
-    private List<String> fields;
-
+    /**
+     * Content Data
+     */
     @Schema(description = "Content Data")
     private List<Data> content;
 
+    /**
+     * Bulletin Metrics Data
+     */
     @lombok.Data
     @Builder
     @AllArgsConstructor
     @NoArgsConstructor
     public static class Data {
+
+        /**
+         * Monitor Name
+         */
         @Schema(title = "Monitor name")
         private String monitorName;
 
+        /**
+         * Monitor ID
+         */
         @Schema(title = "Monitor ID")
         private Long monitorId;
 
+        /**
+         * Monitor IP
+         */
         @Schema(title = "Monitor IP")
         private String host;
 
+        /**
+         * Monitor Metrics
+         */
         @Schema(title = "Monitor Metrics")
         private List<Metric> metrics;
     }
 
+    /**
+     * Metrics Data
+     */
     @lombok.Data
     @Builder
     @AllArgsConstructor
@@ -74,13 +90,23 @@ public class BulletinMetricsData {
     @Schema(description = "Metrics Data")
     public static class Metric{
 
+        /**
+         * Metric type
+         */
         @Schema(title = "Metric type")
         private String name;
 
+        /**
+         * Metric fields
+         */
         @Schema(title = "Metric fields")
         private List<List<Field>> fields;
     }
 
+
+    /**
+     * Metrics field
+     */
     @lombok.Data
     @Builder
     @AllArgsConstructor
@@ -88,12 +114,21 @@ public class BulletinMetricsData {
     @Schema(description = "Metrics field")
     public static class Field{
 
+        /**
+         * Field name
+         */
         @Schema(title = "Field name")
         private String key;
 
+        /**
+         * Field unit
+         */
         @Schema(title = "Field unit")
         private String unit;
 
+        /**
+         * Field value
+         */
         @Schema(title = "Field value")
         private String value;
     }
diff --git 
a/common/src/main/java/org/apache/hertzbeat/common/util/JsonUtil.java 
b/common/src/main/java/org/apache/hertzbeat/common/util/JsonUtil.java
index b38deacce..b95619bb2 100644
--- a/common/src/main/java/org/apache/hertzbeat/common/util/JsonUtil.java
+++ b/common/src/main/java/org/apache/hertzbeat/common/util/JsonUtil.java
@@ -107,8 +107,8 @@ public final class JsonUtil {
             return false;
         }
         jsonStr = jsonStr.trim();
-        if (!(jsonStr.startsWith("{") && jsonStr.endsWith("}")) &&
-                !(jsonStr.startsWith("[") && jsonStr.endsWith("]"))) {
+        if (!(jsonStr.startsWith("{") && jsonStr.endsWith("}"))
+                && !(jsonStr.startsWith("[") && jsonStr.endsWith("]"))) {
             return false;
         }
         try {
diff --git 
a/manager/src/main/java/org/apache/hertzbeat/manager/controller/BulletinController.java
 
b/manager/src/main/java/org/apache/hertzbeat/manager/controller/BulletinController.java
index ebcd4cd05..46d5811ba 100644
--- 
a/manager/src/main/java/org/apache/hertzbeat/manager/controller/BulletinController.java
+++ 
b/manager/src/main/java/org/apache/hertzbeat/manager/controller/BulletinController.java
@@ -40,8 +40,6 @@ import org.apache.hertzbeat.manager.service.BulletinService;
 import org.apache.hertzbeat.manager.service.MonitorService;
 import org.apache.hertzbeat.warehouse.store.realtime.RealTimeDataReader;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -73,6 +71,7 @@ public class BulletinController {
     /**
      * add a new bulletin
      */
+
     @PostMapping
     public ResponseEntity<Message<Void>> addNewBulletin(@Valid @RequestBody 
BulletinDto bulletinDto) {
         try {
@@ -104,7 +103,7 @@ public class BulletinController {
             @RequestParam List<String> names) {
         try {
             bulletinService.deleteBulletinByName(names);
-        }catch (Exception e) {
+        } catch (Exception e) {
             return ResponseEntity.ok(Message.fail(FAIL_CODE, "Delete failed!" 
+ e.getMessage()));
         }
         return ResponseEntity.ok(Message.success("Delete success!"));
@@ -120,20 +119,11 @@ public class BulletinController {
             return ResponseEntity.ok(Message.fail(FAIL_CODE, "real time store 
not available"));
         }
 
-        Pageable pageable = PageRequest.of(pageIndex, pageSize);
         Bulletin bulletin = bulletinService.getBulletinByName(name);
 
         BulletinMetricsData.BulletinMetricsDataBuilder contentBuilder = 
BulletinMetricsData.builder()
-                .name(bulletin.getName())
-                .column(bulletin.getMetrics());
-
-
+                .name(bulletin.getName());
         BulletinMetricsData data = buildBulletinMetricsData(contentBuilder, 
bulletin);
-
-
-
-//        Page<BulletinMetricsData> metricsDataPage = new PageImpl<>(data, 
pageable, data.getData().size());
-
         return ResponseEntity.ok(Message.success(data));
     }
 
@@ -149,37 +139,27 @@ public class BulletinController {
             List<BulletinMetricsData.Metric> metrics = new ArrayList<>();
             Map<String, List<String>> fieldMap = 
JsonUtil.fromJson(bulletin.getFields(), new TypeReference<>() {});
 
-            if (fieldMap != null) {
-                // Convert entry set to a list and sort it
-                List<Map.Entry<String, List<String>>> entries = new 
ArrayList<>(fieldMap.entrySet());
-                entries.sort(Map.Entry.comparingByKey());
 
-                for (Map.Entry<String, List<String>> entry : entries) {
+            if (fieldMap != null) {
+                for (Map.Entry<String, List<String>> entry : 
fieldMap.entrySet()) {
                     String metric = entry.getKey();
                     List<String> fields = entry.getValue();
                     BulletinMetricsData.Metric.MetricBuilder metricBuilder = 
BulletinMetricsData.Metric.builder()
                             .name(metric);
                     CollectRep.MetricsData currentMetricsData = 
realTimeDataReader.getCurrentMetricsData(monitorId, metric);
-                    List<List<BulletinMetricsData.Field>> fieldsList = 
(currentMetricsData != null) ?
-                            buildFieldsListFromCurrentData(currentMetricsData) 
:
-                            buildFieldsListNoData(metric, fields);
+                    List<List<BulletinMetricsData.Field>> fieldsList = 
(currentMetricsData != null)
+                            ? 
buildFieldsListFromCurrentData(currentMetricsData) : 
buildFieldsListNoData(metric, fields);
                     metricBuilder.fields(fieldsList);
                     metrics.add(metricBuilder.build());
                 }
             }
-
-
             dataBuilder.metrics(metrics);
             dataList.add(dataBuilder.build());
         }
-
         contentBuilder.content(dataList);
         return contentBuilder.build();
     }
 
-
-
-
     private List<List<BulletinMetricsData.Field>> 
buildFieldsListFromCurrentData(CollectRep.MetricsData currentMetricsData) {
         return currentMetricsData.getValuesList().stream()
                 .map(valueRow -> {
diff --git 
a/manager/src/main/java/org/apache/hertzbeat/manager/dao/BulletinDao.java 
b/manager/src/main/java/org/apache/hertzbeat/manager/dao/BulletinDao.java
index 9353f1b73..0be6a8320 100644
--- a/manager/src/main/java/org/apache/hertzbeat/manager/dao/BulletinDao.java
+++ b/manager/src/main/java/org/apache/hertzbeat/manager/dao/BulletinDao.java
@@ -1,21 +1,18 @@
 /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
  *
- *  * Licensed to the Apache Software Foundation (ASF) under one or more
- *  * contributor license agreements.  See the NOTICE file distributed with
- *  * this work for additional information regarding copyright ownership.
- *  * The ASF licenses this file to You 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.
- *
+ *     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.apache.hertzbeat.manager.dao;
@@ -23,11 +20,12 @@ package org.apache.hertzbeat.manager.dao;
 
 import java.util.List;
 import org.apache.hertzbeat.common.entity.manager.bulletin.Bulletin;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 
+/**
+ * BulletinDao
+ */
 public interface BulletinDao extends JpaRepository<Bulletin, Long>, 
JpaSpecificationExecutor<Bulletin> {
     /**
      * Delete Bulletin by name
diff --git 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/BulletinService.java
 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/BulletinService.java
index cb81c8f93..6b248d219 100644
--- 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/BulletinService.java
+++ 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/BulletinService.java
@@ -24,7 +24,6 @@ import 
org.apache.hertzbeat.common.entity.manager.bulletin.BulletinDto;
 import org.apache.hertzbeat.common.entity.manager.bulletin.BulletinVo;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.domain.Specification;
 
 /**
@@ -41,6 +40,7 @@ public interface BulletinService {
      * Get Bulletin by name
      */
     Bulletin getBulletinByName(String name);
+
     /**
      * Get Bulletin by id
      */
@@ -51,10 +51,6 @@ public interface BulletinService {
      */
     List<String> getAllNames();
 
-    /**
-     * Get metrics by name
-     */
-    List<String> getMetricsByName(String name);
 
     /**
      * delete Bulletin by id
diff --git 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/BulletinServiceImpl.java
 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/BulletinServiceImpl.java
index d4070fce6..b5da411ed 100644
--- 
a/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/BulletinServiceImpl.java
+++ 
b/manager/src/main/java/org/apache/hertzbeat/manager/service/impl/BulletinServiceImpl.java
@@ -21,26 +21,23 @@
 package org.apache.hertzbeat.manager.service.impl;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.TreeMap;
 import java.util.stream.Collectors;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.hertzbeat.common.entity.manager.bulletin.Bulletin;
 import org.apache.hertzbeat.common.entity.manager.bulletin.BulletinDto;
 import org.apache.hertzbeat.common.entity.manager.bulletin.BulletinVo;
 import org.apache.hertzbeat.common.util.JsonUtil;
 import org.apache.hertzbeat.common.util.SnowFlakeIdGenerator;
 import org.apache.hertzbeat.manager.dao.BulletinDao;
-import org.apache.hertzbeat.common.entity.manager.bulletin.Bulletin;
-import org.apache.hertzbeat.manager.dao.MonitorDao;
 import org.apache.hertzbeat.manager.service.BulletinService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageImpl;
 import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.domain.Specification;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -59,8 +56,6 @@ public class BulletinServiceImpl implements BulletinService {
 
     /**
      * validate Bulletin
-     *
-     * @param bulletinDto
      */
     @Override
     public void validate(BulletinDto bulletinDto) throws 
IllegalArgumentException {
@@ -70,9 +65,6 @@ public class BulletinServiceImpl implements BulletinService {
         if (bulletinDto.getApp() == null || bulletinDto.getApp().isEmpty()) {
             throw new IllegalArgumentException("Bulletin app cannot be null or 
empty");
         }
-        if (bulletinDto.getMetrics() == null || 
bulletinDto.getMetrics().isEmpty()) {
-            throw new IllegalArgumentException("Bulletin metrics cannot be 
null or empty");
-        }
         if (bulletinDto.getFields() == null || 
bulletinDto.getFields().isEmpty()) {
             throw new IllegalArgumentException("Bulletin fields cannot be null 
or empty");
         }
@@ -98,15 +90,6 @@ public class BulletinServiceImpl implements BulletinService {
         return 
bulletinDao.findAll().stream().map(Bulletin::getName).distinct().toList();
     }
 
-    /**
-     * Get metrics by name
-     *
-     * @param name
-     */
-    @Override
-    public List<String> getMetricsByName(String name) {
-        return bulletinDao.findByName(name).getMetrics();
-    }
 
     /**
      * Save Bulletin
@@ -131,7 +114,6 @@ public class BulletinServiceImpl implements BulletinService 
{
             Map<String, List<String>> sortedMap = new TreeMap<>(map);
             String fields = JsonUtil.toJson(sortedMap);
             bulletin.setFields(fields);
-            bulletin.setMetrics(bulletinDto.getMetrics());
             bulletin.setMonitorIds(bulletinDto.getMonitorIds());
             bulletin.setApp(bulletinDto.getApp());
             bulletinDao.save(bulletin);
@@ -158,7 +140,6 @@ public class BulletinServiceImpl implements BulletinService 
{
                 vo.setId(bulletin.getId());
                 vo.setName(bulletin.getName());
                 vo.setTags(bulletin.getTags());
-                vo.setMetrics(bulletin.getMetrics());
                 vo.setMonitorId(bulletin.getMonitorIds());
                 vo.setApp(bulletin.getApp());
                 return vo;
diff --git a/web-app/src/app/pojo/BulletinDefine.ts 
b/web-app/src/app/pojo/BulletinDefine.ts
index 1606ff834..751200574 100644
--- a/web-app/src/app/pojo/BulletinDefine.ts
+++ b/web-app/src/app/pojo/BulletinDefine.ts
@@ -24,6 +24,5 @@ export class BulletinDefine {
   name!: string;
   monitorIds!: number[];
   app!: string;
-  metrics!: string[];
   fields: Fields = {};
 }
diff --git a/web-app/src/app/routes/bulletin/bulletin.component.html 
b/web-app/src/app/routes/bulletin/bulletin.component.html
index 67b106a07..3fafcd88b 100644
--- a/web-app/src/app/routes/bulletin/bulletin.component.html
+++ b/web-app/src/app/routes/bulletin/bulletin.component.html
@@ -18,7 +18,7 @@
 -->
 
 <app-help-message-show
-  [help_message_content]="'自定义监控看板'"
+  [help_message_content]="'bulletin.help.message.content' | i18n"
   [guild_link]="'bulletin.help.link' | i18n"
   [module_name]="'menu.alert.setting'"
   [icon_name]="'calculator'"
@@ -33,21 +33,21 @@
     </button>
     <button nz-button nzType="primary" (click)="onNewBulletinDefine()">
       <i nz-icon nzType="appstore-add" nzTheme="outline"></i>
-      新增看板项
+      {{ 'bulletin.new' | i18n }}
     </button>
     <button nz-button nzType="primary" nzDanger 
(click)="onDeleteBulletinDefines()">
       <i nz-icon nzType="delete" nzTheme="outline"></i>
-      删除看板项
+      {{ 'bulletin.delete' | i18n }}
     </button>
   </ng-template>
 </app-toolbar>
 
-<nz-tabset nzType="card">
+<nz-tabset nzType="card" (nzSelectedIndexChange)="onTabChange($event)">
   <nz-tab *ngFor="let tab of tabs" [nzTitle]="tab">
     <ng-container *ngIf="tabDefines">
       <nz-table
         #fixedTable
-        [nzData]="tabDefines.data"
+        [nzData]="tabDefines.data.content"
         [nzPageIndex]="pageIndex"
         [nzPageSize]="pageSize"
         [nzTotal]="total"
@@ -62,49 +62,46 @@
         class="table"
       >
         <thead>
-<!--          <tr>-->
-<!--            <th nzAlign="center" nzWidth="7%" [rowSpan]="2">App</th>-->
-<!--            <th nzAlign="center" nzWidth="7%" [rowSpan]="2">Host</th>-->
-<!--            <ng-container *ngFor="let metric of tabDefines.data.column">-->
-<!--              <th nzAlign="center" [colSpan]="getKeys(metric).length">-->
-<!--                {{ metric }}-->
-<!--              </th>-->
-<!--            </ng-container>-->
-<!--          </tr>-->
-<!--          <tr>-->
-<!--            <ng-container *ngFor="let metric of tabDefines.data.column">-->
-<!--              <ng-container *ngFor="let field of getKeys(metric)">-->
-<!--                <th nzAlign="center" [colSpan]="1">-->
-<!--                  {{ field }}-->
-<!--                </th>-->
-<!--              </ng-container>-->
-<!--            </ng-container>-->
-<!--          </tr>-->
+          <tr>
+            <th nzAlign="center" nzWidth="7%" [rowSpan]="2">App</th>
+            <th nzAlign="center" nzWidth="7%" [rowSpan]="2">Host</th>
+            <ng-container *ngFor="let metric of getMetrics()">
+              <th nzAlign="center" [colSpan]="getKeys(metric).length">
+                {{ metric }}
+              </th>
+            </ng-container>
+          </tr>
+          <tr>
+            <ng-container *ngFor="let metric of getMetrics()">
+              <ng-container *ngFor="let field of getKeys(metric)">
+                <th nzAlign="center" [colSpan]="1">
+                  {{ field }}
+                </th>
+              </ng-container>
+            </ng-container>
+          </tr>
         </thead>
-
         <tbody>
           <ng-container *ngFor="let content of fixedTable.data">
-            <ng-container *ngFor="let rowIndex of getRowIndexes()">
-              <tr>
-                <ng-container *ngIf="rowIndex === 0">
-                  <td nzAlign="center" 
[rowSpan]="tabDefines.data.content.length">{{ content.monitorName }}</td>
-                  <td nzAlign="center" 
[rowSpan]="tabDefines.data.content.length">{{ content.host }}</td>
+            <tr>
+              <td nzAlign="center" [rowSpan]="1">{{ content.monitorName }}</td>
+              <td nzAlign="center" [rowSpan]="1">{{ content.host }}</td>
+              <ng-container *ngFor="let metric of content.metrics">
+                <ng-container *ngFor="let field of metric.fields">
+                  <ng-container *ngFor="let item of field">
+                    <td nzAlign="center">
+                      <ng-container *ngIf="item.value === 'No Data'; else 
hasData">
+                        <nz-tag nzColor="warning">No Data Available</nz-tag>
+                      </ng-container>
+                      <ng-template #hasData>
+                        {{ item.value }}
+                        <nz-tag *ngIf="item.unit !== ''" nzColor="success">{{ 
item.unit }}</nz-tag>
+                      </ng-template>
+                    </td>
+                  </ng-container>
                 </ng-container>
-                <ng-container *ngFor="let metric of content.metrics">
-                  <td>
-                    <div *ngFor="let field of metric.fields">
-                      <div *ngFor="let item of field">
-                        <span>{{ item.key }}: </span>
-                        <nz-tag *ngIf="item.value === 'No Data'" 
nzColor="warning">
-                          {{ 'monitors.detail.value.null' | i18n }}
-                        </nz-tag>
-                        <nz-tag *ngIf="item.value !== 'No Data'" 
nzColor="success"> {{ item.value }} {{ item.unit }} </nz-tag>
-                      </div>
-                    </div>
-                  </td>
-                </ng-container>
-              </tr>
-            </ng-container>
+              </ng-container>
+            </tr>
           </ng-container>
         </tbody>
       </nz-table>
@@ -115,7 +112,7 @@
 <!-- new bulletin modal -->
 <nz-modal
   [(nzVisible)]="isManageModalVisible"
-  [nzTitle]="isManageModalAdd ? '新增看板' : '编辑看板'"
+  [nzTitle]="'bulletin.new' | i18n"
   (nzOnCancel)="onManageModalCancel()"
   (nzOnOk)="onManageModalOk()"
   nzMaskClosable="false"
@@ -177,7 +174,6 @@
             [nzShowSelectAll]="false"
             [nzRenderList]="[leftRenderList, null]"
             (nzChange)="transferChange($event)"
-            required
           >
             <ng-template #leftRenderList let-items 
let-onItemSelect="onItemSelect">
               <nz-tree
@@ -210,7 +206,7 @@
 <!-- delete bulletin modal -->
 <nz-modal
   [(nzVisible)]="isDeleteModalVisible"
-  [nzTitle]="'删除看板'"
+  [nzTitle]="'bulletin.delete' | i18n"
   (nzOnCancel)="onDeleteModalCancel()"
   (nzOnOk)="onDeleteModalOk()"
   nzMaskClosable="false"
diff --git a/web-app/src/app/routes/bulletin/bulletin.component.ts 
b/web-app/src/app/routes/bulletin/bulletin.component.ts
index 58b4508a5..8767e0425 100644
--- a/web-app/src/app/routes/bulletin/bulletin.component.ts
+++ b/web-app/src/app/routes/bulletin/bulletin.component.ts
@@ -17,7 +17,6 @@
  * under the License.
  */
 
-import { HttpParams } from '@angular/common/http';
 import { Component, Inject, OnInit } from '@angular/core';
 import { I18NService } from '@core';
 import { ALAIN_I18N_TOKEN } from '@delon/theme';
@@ -83,7 +82,6 @@ export class BulletinComponent implements OnInit {
 
   onNewBulletinDefine() {
     this.define = new BulletinDefine();
-    this.define.metrics = [];
     this.define.monitorIds = [];
     this.isManageModalAdd = true;
     this.isManageModalVisible = true;
@@ -130,7 +128,6 @@ export class BulletinComponent implements OnInit {
 
   onManageModalOk() {
     this.isManageModalOkLoading = true;
-    this.define.metrics = Array.from(this.metrics);
     this.define.fields = this.fields;
     if (this.isManageModalAdd) {
       const modalOk$ = this.bulletinDefineSvc
@@ -377,6 +374,7 @@ export class BulletinComponent implements OnInit {
           metricData$.unsubscribe();
           if (message.code === 0 && message.data) {
             this.tabDefines = message;
+            console.log(this.tabDefines.data);
           } else if (message.code !== 0) {
             this.notifySvc.warning(`${message.msg}`, '');
             console.info(`${message.msg}`);
@@ -393,6 +391,15 @@ export class BulletinComponent implements OnInit {
     this.tableLoading = false;
   }
 
+  getMetrics(): string[] {
+    this.tabDefines.data.content.forEach((item: any) => {
+      item.metrics.forEach((metric: any) => {
+        this.metrics.add(metric.name);
+      });
+    });
+    return Array.from(this.metrics);
+  }
+
   getKeys(metricName: string): string[] {
     const result = new Set<string>();
 
@@ -413,7 +420,6 @@ export class BulletinComponent implements OnInit {
   onTablePageChange(params: NzTableQueryParams): void {
     const { pageSize, pageIndex } = params;
 
-    // 只有当页码或每页条数变化时才获取数据
     if (pageIndex !== this.pageIndex || pageSize !== this.pageSize) {
       this.pageIndex = pageIndex;
       this.pageSize = pageSize;
@@ -423,9 +429,7 @@ export class BulletinComponent implements OnInit {
 
   getRowIndexes() {
     const maxRowSpan = this.tabDefines.data.content.length;
-    var numbers = Array.from({ length: maxRowSpan }, (_, index) => index);
-    console.log(numbers);
-    return numbers;
+    return Array.from({ length: maxRowSpan }, (_, index) => index);
   }
 
   isDeleteModalVisible: boolean = false;
@@ -467,4 +471,13 @@ export class BulletinComponent implements OnInit {
   }
 
   protected readonly Array = Array;
+
+  onTabChange($event: number) {
+    this.tableLoading = true;
+    this.bulletinName = this.tabs[$event];
+    this.tabDefines = [];
+    this.loadData(this.pageIndex - 1, this.pageSize);
+    console.log(this.tabDefines);
+    this.tableLoading = false;
+  }
 }
diff --git a/web-app/src/assets/i18n/en-US.json 
b/web-app/src/assets/i18n/en-US.json
index 9869a02dd..b7edd6eae 100644
--- a/web-app/src/assets/i18n/en-US.json
+++ b/web-app/src/assets/i18n/en-US.json
@@ -43,6 +43,18 @@
       "silence": "Alarm Silence",
       "dispatch": "Notification"
     },
+    "bulletin": {
+      "new": "Add New Bulletin Item",
+      "delete": "Delete Bulletin Item",
+      "name": "Bulletin Name",
+      "name.placeholder": "Please enter a custom bulletin name",
+      "monitor.type": "Monitor Type",
+      "monitor.name": "Monitor Task Name",
+      "monitor.metrics": "Monitor Metrics",
+      "help.message.content": "Custom Monitoring Bulletin",
+      "help.content": "Custom monitoring bulletin, displaying selected metrics 
of a specific monitor in table form",
+      "help.link": ""
+    },
     "advanced": {
       "": "Advanced",
       "collector": "Collector Cluster",
diff --git a/web-app/src/assets/i18n/zh-CN.json 
b/web-app/src/assets/i18n/zh-CN.json
index 74984a2d1..3692f086c 100644
--- a/web-app/src/assets/i18n/zh-CN.json
+++ b/web-app/src/assets/i18n/zh-CN.json
@@ -131,17 +131,15 @@
     }
   },
   "bulletin": {
+    "new": "新增看板项",
+    "delete": "删除看板项",
     "name": "看板名称",
     "name.placeholder": "请输入自定义看板名称",
     "monitor.type": "监控类型",
     "monitor.name": "监控任务名称",
     "monitor.metrics": "监控指标",
-    "content": "公告内容",
-    "time": "发布时间",
-    "status": "状态",
-    "status.online": "已发布",
-    "status.offline": "未发布",
-    "help.content": "自定义监控看板,可以展示某种监控的duo'tai服务器的,磁盘、内存、一个总的概览,像是一个表格",
+    "help.message.content": "自定义监控看板",
+    "help.content": "自定义监控看板,以表格形式展示某种监控的自选指标",
     "help.link": ""
   },
   "question.link": "https://hertzbeat.apache.org/zh-cn/docs/help/issue";,
diff --git a/web-app/src/assets/i18n/zh-TW.json 
b/web-app/src/assets/i18n/zh-TW.json
index 7ebb6c00b..46d3fee76 100644
--- a/web-app/src/assets/i18n/zh-TW.json
+++ b/web-app/src/assets/i18n/zh-TW.json
@@ -43,6 +43,18 @@
       "silence": "告警靜默",
       "dispatch": "消息通知"
     },
+    "bulletin": {
+      "new": "新增看板項",
+      "delete": "刪除看板項",
+      "name": "看板名稱",
+      "name.placeholder": "請輸入自定義看板名稱",
+      "monitor.type": "監控類型",
+      "monitor.name": "監控任務名稱",
+      "monitor.metrics": "監控指標",
+      "help.message.content": "自定義監控看板",
+      "help.content": "自定義監控看板,以表格形式展示某種監控的自選指標",
+      "help.link": ""
+    },
     "advanced": {
       "": "高级",
       "collector": "採集集群",


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to