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 1538e9125 feat(bulletin): implement pagination and sorting for metrics
data
1538e9125 is described below
commit 1538e912593356f3154ae7cc0af77350e924a328
Author: zqr10159 <[email protected]>
AuthorDate: Wed Jul 31 23:30:54 2024 +0800
feat(bulletin): implement pagination and sorting for metrics data
This commit introduces support for pagination and sorting in the Bulletin
component. It modifies the service layer to handle paged requests and
sortsthe data accordingly. The component's template is updated to include
pagination
controls and to bind to the new page size and index properties.
Additionally, a
custom dropdown render template is added for selecting monitors.
BREAKING CHANGE: The `getAllMonitorMetricsData` method in
`BulletinDefineService`
has been replaced with `getMonitorMetricsData`, which now expects pagination
parameters. The `BulletinController` also now expects `pageIndex` and
`pageSize`
parameters for fetching metrics data. These changes may affect consumers
ofthese APIs who were not expecting pagination support.
---
.../manager/controller/BulletinController.java | 18 ++++---
.../hertzbeat/manager/service/BulletinService.java | 5 ++
.../manager/service/impl/BulletinServiceImpl.java | 8 +++
.../app/routes/bulletin/bulletin.component.html | 13 ++++-
.../src/app/routes/bulletin/bulletin.component.ts | 62 ++++++++++++++++++----
web-app/src/app/service/bulletin-define.service.ts | 28 ++++++++--
6 files changed, 114 insertions(+), 20 deletions(-)
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 4f5c4a6db..35b87639b 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
@@ -52,7 +52,9 @@ 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.Page;
+import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
@@ -159,17 +161,22 @@ public class BulletinController {
@GetMapping("/metrics")
@Operation(summary = "Query All Bulletin Real Time Metrics Data",
description = "Query All Bulletin real-time metrics data of monitoring
indicators")
- public ResponseEntity<Message<List<BulletinMetricsData>>>
getAllMetricsData() {
+ public ResponseEntity<Message<Page<BulletinMetricsData>>>
getAllMetricsData(
+ @RequestParam(defaultValue = "0", name = "pageIndex") int
pageIndex,
+ @RequestParam(defaultValue = "10", name = "pageSize") int
pageSize) {
if (!realTimeDataReader.isServerAvailable()) {
return ResponseEntity.ok(Message.fail(FAIL_CODE, "real time store
not available"));
}
- List<Bulletin> bulletinList = bulletinService.listBulletin();
- List<BulletinMetricsData> dataList = bulletinList.stream()
+ Pageable pageable = PageRequest.of(pageIndex, pageSize);
+ Page<Bulletin> bulletinPage = bulletinService.listBulletin(pageable);
+ List<BulletinMetricsData> dataList = bulletinPage.stream()
.map(this::buildBulletinMetricsData)
.toList();
- return ResponseEntity.ok(Message.success(dataList));
+ Page<BulletinMetricsData> metricsDataPage = new PageImpl<>(dataList,
pageable, bulletinPage.getTotalElements());
+
+ return ResponseEntity.ok(Message.success(metricsDataPage));
}
private BulletinMetricsData buildBulletinMetricsData(Bulletin bulletin) {
@@ -247,5 +254,4 @@ public class BulletinController {
return Collections.singletonList(fields);
}
-
-}
+}
\ No newline at end of file
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 e6bd45592..7c5788a0d 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,6 +24,7 @@ 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 +42,10 @@ public interface BulletinService {
*/
List<Bulletin> listBulletin();
+ /**
+ * Pageable query Bulletin
+ */
+ Page<Bulletin> listBulletin(Pageable pageable);
/**
* Get 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 84316e485..5745dff3b 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
@@ -78,6 +78,14 @@ public class BulletinServiceImpl implements BulletinService {
return bulletinDao.findAll();
}
+ /**
+ * Pageable query Bulletin
+ */
+ @Override
+ public Page<Bulletin> listBulletin(Pageable pageable) {
+ return bulletinDao.findAll(pageable);
+ }
+
/**
* Save Bulletin
*/
diff --git a/web-app/src/app/routes/bulletin/bulletin.component.html
b/web-app/src/app/routes/bulletin/bulletin.component.html
index 8de4ee818..3a1fd1596 100644
--- a/web-app/src/app/routes/bulletin/bulletin.component.html
+++ b/web-app/src/app/routes/bulletin/bulletin.component.html
@@ -45,13 +45,17 @@
<nz-tabset nzType="card">
<nz-tab *ngFor="let bulletinTab of tabDefines" [nzTitle]="bulletinTab.name">
<nz-table
- *ngIf="bulletinTab.data.length"
#fixedTable
[nzData]="bulletinTab.data"
+ [nzPageIndex]="pageIndex"
+ [nzPageSize]="pageSize"
+ [nzTotal]="total"
nzFrontPagination="false"
[nzLoading]="tableLoading"
nzShowSizeChanger
[nzShowTotal]="rangeTemplate"
+ [nzPageSizeOptions]="[8, 15, 25]"
+ (nzQueryParams)="onTablePageChange($event)"
nzShowPagination="true"
[nzScroll]="{ x: 'auto' }"
nzBordered
@@ -149,11 +153,17 @@
[(ngModel)]="define.monitorIds"
(nzOnSearch)="onSearchMonitorsByApp(define.app)"
nzMode="multiple"
+ [nzDropdownRender]="dropdownRenderTemplate"
>
<ng-container *ngFor="let monitor of monitors">
<nz-option *ngIf="isMonitorListLoading" [nzValue]="monitor.id"
[nzLabel]="monitor.name"></nz-option>
</ng-container>
</nz-select>
+ <ng-template #dropdownRenderTemplate>
+ <div class="custom-dropdown">
+ <button nz-button (click)="toggleSelectAll()">Toggle Select
All</button>
+ </div>
+ </ng-template>
</nz-form-control>
</nz-form-item>
@@ -194,6 +204,7 @@
</div>
</nz-modal>
+
<!-- delete bulletin modal -->
<nz-modal
[(nzVisible)]="isDeleteModalVisible"
diff --git a/web-app/src/app/routes/bulletin/bulletin.component.ts
b/web-app/src/app/routes/bulletin/bulletin.component.ts
index 1edf13a84..c7ee3e533 100644
--- a/web-app/src/app/routes/bulletin/bulletin.component.ts
+++ b/web-app/src/app/routes/bulletin/bulletin.component.ts
@@ -31,6 +31,7 @@ import { Monitor } from '../../pojo/Monitor';
import { AppDefineService } from '../../service/app-define.service';
import { BulletinDefineService } from '../../service/bulletin-define.service';
import { MonitorService } from '../../service/monitor.service';
+import {HttpParams} from "@angular/common/http";
@Component({
selector: 'app-bulletin',
@@ -59,13 +60,16 @@ export class BulletinComponent implements OnInit {
checkedNodeList: NzTreeNode[] = [];
monitors: Monitor[] = [];
rawData: any[] = [];
+ pageIndex: number = 1;
+ pageSize: number = 8;
+ total: number = 0;
ngOnInit(): void {
- this.loadData();
+ this.loadData(this.pageIndex - 1, this.pageSize);
}
sync() {
- this.loadData();
+ this.loadData(this.pageIndex - 1, this.pageSize);
}
onNewBulletinDefine() {
@@ -89,7 +93,7 @@ export class BulletinComponent implements OnInit {
deleteDefines$.unsubscribe();
if (message.code === 0) {
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.delete-success'), '');
- this.loadData();
+ this.loadData(this.pageIndex - 1, this.pageSize);
} else {
this.tableLoading = false;
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.delete-fail'),
message.msg);
@@ -134,7 +138,7 @@ export class BulletinComponent implements OnInit {
if (message.code === 0) {
this.isManageModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.new-success'), '');
- this.loadData();
+ this.loadData(this.pageIndex - 1, this.pageSize);
this.resetManageModalData();
} else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.new-fail'), message.msg);
@@ -158,7 +162,7 @@ export class BulletinComponent implements OnInit {
if (message.code === 0) {
this.isManageModalVisible = false;
this.notifySvc.success(this.i18nSvc.fanyi('common.notify.edit-success'), '');
- this.loadData();
+ this.loadData(this.pageIndex - 1, this.pageSize);
} else {
this.notifySvc.error(this.i18nSvc.fanyi('common.notify.edit-fail'),
message.msg);
}
@@ -303,7 +307,13 @@ export class BulletinComponent implements OnInit {
treeCheckBoxChange(event: NzFormatEmitEvent, onItemSelect: (item:
NzTreeNodeOptions) => void): void {
this.checkBoxChange(event.node!, onItemSelect);
}
-
+ toggleSelectAll() {
+ if (this.define.monitorIds.length === this.monitors.length) {
+ this.define.monitorIds = [];
+ } else {
+ this.define.monitorIds = this.monitors.map(monitor => monitor.id);
+ }
+ }
checkBoxChange(node: NzTreeNode, onItemSelect: (item: NzTreeNodeOptions) =>
void): void {
if (node.isDisabled) {
return;
@@ -330,13 +340,14 @@ export class BulletinComponent implements OnInit {
});
}
- loadData() {
- const metricData$ =
this.bulletinDefineSvc.getAllMonitorMetricsData().subscribe(
+ loadData(page: number = 0, size: number = 10) {
+ const metricData$ = this.bulletinDefineSvc.getMonitorMetricsData(page,
size).subscribe(
message => {
metricData$.unsubscribe();
if (message.code === 0 && message.data) {
this.tableLoading = false;
- this.rawData = message.data;
+ this.rawData = message.data.content; // 假设返回的数据中包含分页内容的字段为 'content'
+ this.total = message.data.totalElements; // 假设返回的数据中包含总元素数量的字段为
'totalElements'
this.updateTabDefines();
} else if (message.code !== 0) {
this.notifySvc.warning(`${message.msg}`, '');
@@ -414,7 +425,38 @@ export class BulletinComponent implements OnInit {
}
return maxRowSpan;
}
-
+ onTablePageChange(params: NzTableQueryParams) {
+ const { pageSize, pageIndex, sort, filter } = params;
+ this.pageIndex = pageIndex;
+ this.pageSize = pageSize;
+ const currentSort = sort.find(item => item.value !== null);
+ const sortField = (currentSort && currentSort.key) || null;
+ const sortOrder = (currentSort && currentSort.value) || null;
+ this.changeBulletinTable(sortField, sortOrder);
+ }
+ changeBulletinTable(sortField?: string | null, sortOrder?: string | null) {
+ this.tableLoading = true;
+ let monitorInit$ = this.bulletinDefineSvc
+ .getMonitorMetricsData(this.pageIndex - 1, this.pageSize, sortField,
sortOrder)
+ .subscribe(
+ message => {
+ this.tableLoading = false;
+ if (message.code === 0) {
+ let page = message.data;
+ this.monitors = page.content;
+ this.pageIndex = page.number + 1;
+ this.total = page.totalElements;
+ } else {
+ console.warn(message.msg);
+ }
+ monitorInit$.unsubscribe();
+ },
+ error => {
+ this.tableLoading = false;
+ monitorInit$.unsubscribe();
+ }
+ );
+ }
getRowIndexes(data: { [x: string]: string | any[] }, bulletinTab: {
bulletinColumn: { [x: string]: any } }) {
const maxRowSpan = this.getMaxRowSpan(data, bulletinTab);
return Array.from({ length: maxRowSpan }, (_, index) => index);
diff --git a/web-app/src/app/service/bulletin-define.service.ts
b/web-app/src/app/service/bulletin-define.service.ts
index 03164df77..e9832fb4c 100644
--- a/web-app/src/app/service/bulletin-define.service.ts
+++ b/web-app/src/app/service/bulletin-define.service.ts
@@ -22,6 +22,8 @@ import {HttpClient, HttpParams} from "@angular/common/http";
import {Observable} from "rxjs";
import {Message} from "../pojo/Message";
import {BulletinDefine} from "../pojo/BulletinDefine";
+import {Page} from "../pojo/Page";
+import {Monitor} from "../pojo/Monitor";
const bulletin_define_uri = '/bulletin';
@@ -48,10 +50,30 @@ export class BulletinDefineService {
return this.http.delete<Message<any>>(bulletin_define_uri, { params });
}
-
- public getAllMonitorMetricsData(): Observable<Message<any>> {
- return this.http.get<Message<any>>(`${bulletin_define_uri}/metrics`);
+ public getMonitorMetricsData(
+ pageIndex: number,
+ pageSize: number,
+ sortField?: string | null,
+ sortOrder?: string | null
+ ): Observable<Message<Page<Monitor>>> {
+ pageIndex = pageIndex ? pageIndex : 0;
+ pageSize = pageSize ? pageSize : 8;
+ // 注意HttpParams是不可变对象 需要保存set后返回的对象为最新对象
+ let httpParams = new HttpParams();
+ httpParams = httpParams.appendAll({
+ pageIndex: pageIndex,
+ pageSize: pageSize
+ });
+ if (sortField != null && sortOrder != null) {
+ httpParams = httpParams.appendAll({
+ sort: sortField,
+ order: sortOrder == 'ascend' ? 'asc' : 'desc'
+ });
+ }
+ const options = { params: httpParams };
+ return this.http.get<Message<any>>(`${bulletin_define_uri}/metrics`,
options);
}
+
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]