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

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


The following commit(s) were added to refs/heads/master by this push:
     new 9260bca05 Optimize the dashboard. (#2193)
9260bca05 is described below

commit 9260bca057dca9de073307b88ef2db96f792e9be
Author: Kerwin Bryant <[email protected]>
AuthorDate: Thu Jul 4 18:53:05 2024 +0800

    Optimize the dashboard. (#2193)
---
 .../app/routes/dashboard/dashboard.component.html  | 241 +++++++++++----------
 .../app/routes/dashboard/dashboard.component.less  |  21 ++
 .../app/routes/dashboard/dashboard.component.ts    | 122 ++++++-----
 3 files changed, 216 insertions(+), 168 deletions(-)

diff --git a/web-app/src/app/routes/dashboard/dashboard.component.html 
b/web-app/src/app/routes/dashboard/dashboard.component.html
index 8cef82b0a..f5ca85ae1 100644
--- a/web-app/src/app/routes/dashboard/dashboard.component.html
+++ b/web-app/src/app/routes/dashboard/dashboard.component.html
@@ -290,131 +290,142 @@
 
 <div nz-row nzGutter="16" style="margin-top: 25px; height: 400px">
   <div nz-col [nzXs]="{ span: 24 }" [nzSm]="{ span: 24 }" [nzMd]="{ span: 6 }" 
style="height: 100%">
-    <angular-tag-cloud
-      class="br-4"
-      (clicked)="onTagCloudClick($event)"
-      [font]="'italic bold 6px monospace'"
-      [data]="wordCloudData"
-      [width]="1"
-      [height]="1"
-      [step]="2"
-      [strict]="true"
-      [randomizeAngle]="true"
-      [realignOnResize]="true"
-      [delay]="300"
-      [zoomOnHover]="{ scale: 1.4, transitionTime: 0.6, delay: 0.4 }"
-      [overflow]="false"
-      [background]="'white no-repeat fixed center'"
-    >
-    </angular-tag-cloud>
+    <nz-spin [nzSpinning]="wordCloudDataLoading">
+      <angular-tag-cloud
+        class="br-4"
+        *ngIf="!wordCloudDataLoading"
+        (clicked)="onTagCloudClick($event)"
+        [font]="'italic bold 6px monospace'"
+        [data]="wordCloudData"
+        [width]="1"
+        [height]="1"
+        [step]="2"
+        [strict]="true"
+        [randomizeAngle]="true"
+        [realignOnResize]="true"
+        [delay]="300"
+        [zoomOnHover]="{ scale: 1.4, transitionTime: 0.6, delay: 0.4 }"
+        [overflow]="false"
+        [background]="'white no-repeat fixed center'"
+      >
+      </angular-tag-cloud>
+    </nz-spin>
   </div>
   <div nz-col [nzXs]="{ span: 24 }" [nzSm]="{ span: 24 }" [nzMd]="{ span: 12 
}" style="height: 100%">
-    <div
-      echarts
-      [options]="appsCountEChartOption"
-      theme="default"
-      [autoResize]="true"
-      [loading]="appsCountLoading"
-      (chartClick)="onChartClick($event)"
-      (chartInit)="onAppsCountChartInit($event)"
-      style="width: 100%; height: inherit"
-    ></div>
+    <nz-spin [nzSpinning]="appsCountLoading">
+      <div
+        echarts
+        [options]="appsCountEChartOption"
+        theme="default"
+        [autoResize]="true"
+        [loading]="appsCountLoading"
+        (chartClick)="onChartClick($event)"
+        (chartInit)="onAppsCountChartInit($event)"
+        style="width: 100%; height: inherit"
+      ></div>
+    </nz-spin>
   </div>
   <div nz-col [nzXs]="{ span: 24 }" [nzSm]="{ span: 24 }" [nzMd]="{ span: 6 }" 
style="height: 100%">
-    <div style="overflow-y: scroll; height: inherit">
-      <nz-card *ngFor="let item of collectors; let i = index" 
class="rounded-lg" nzBordered="false" [nzTitle]="collectorCardTitle">
-        <nz-card-tab>
-          <nz-tabset nzSize="small">
-            <nz-tab [nzTitle]="'collector.status' | i18n">
-              <div class="rounded-lg" style="text-align: center; width: 100%; 
background-color: #8fccca; padding: 2%">
-                <span [style]="'font-size: x-large; font-weight: bolder;' + 
(item.collector.status == 0 ? 'color: green' : 'color: red')">
-                  {{
-                    item.collector.status == 0 ? 
('monitor.collector.status.online' | i18n) : 
('monitor.collector.status.offline' | i18n)
-                  }}
-                </span>
-              </div>
-            </nz-tab>
-            <nz-tab [nzTitle]="'collector.task' | i18n">
-              <div class="rounded-lg" style="text-align: center; width: 100%; 
background-color: #8fccca; padding: 2%">
-                <span style="font-size: xxx-large; font-weight: bolder; color: 
white">
-                  {{ item.pinMonitorNum + item.dispatchMonitorNum }}
-                </span>
-                <br />
-                <nz-tag style="margin-bottom: 4%; font-weight: bolder">{{ 
'collector.pinned' | i18n }}: {{ item.pinMonitorNum }}</nz-tag>
-                <nz-tag style="margin-bottom: 4%; font-weight: bolder"
-                  >{{ 'collector.dispatched' | i18n }}: {{ 
item.dispatchMonitorNum }}</nz-tag
-                >
-              </div>
-            </nz-tab>
-            <nz-tab [nzTitle]="'collector.start-time' | i18n">
-              <div class="rounded-lg" style="text-align: center; width: 100%; 
background-color: #8fccca; padding: 2%">
-                <span style="font-size: x-large; font-weight: bolder; color: 
white">{{
-                  (item.collector.gmtUpdate | date : 'YYYY-MM-dd 
HH:mm:ss')?.trim()
-                }}</span>
-              </div>
-            </nz-tab>
-            <nz-tab [nzTitle]="'collector.ip' | i18n">
-              <div class="rounded-lg" style="text-align: center; width: 100%; 
background-color: #8fccca; padding: 2%">
-                <span style="font-size: x-large; font-weight: bolder; color: 
white">{{ item.collector.ip }}</span>
-              </div>
-            </nz-tab>
-            <nz-tab [nzTitle]="'collector.node' | i18n">
-              <div class="rounded-lg" style="text-align: center; width: 100%; 
background-color: #8fccca; padding: 2%">
-                <span style="font-size: x-large; font-weight: bolder; color: 
white">{{ item.collector.name }}</span>
-              </div>
-            </nz-tab>
-          </nz-tabset>
-        </nz-card-tab>
-        <ng-template #collectorCardTitle>
-          <span style="font-size: medium; font-weight: bold" nz-tooltip 
[nzTooltipTitle]="item.collector.name">
-            <span nz-icon nzType="bug" nzTheme="outline" style="margin-right: 
4px"></span>
-            <span>{{ 'collector' | i18n }} : {{ item.collector.name }}</span>
-          </span>
-        </ng-template>
-      </nz-card>
-    </div>
+    <nz-spin [nzSpinning]="collectorsLoading">
+      <div style="overflow-y: auto; height: inherit">
+        <nz-card *ngFor="let item of collectors; let i = index" 
class="rounded-lg" nzBordered="false" [nzTitle]="collectorCardTitle">
+          <nz-card-tab>
+            <nz-tabset nzSize="small">
+              <nz-tab [nzTitle]="'collector.status' | i18n">
+                <div class="rounded-lg" style="text-align: center; width: 
100%; background-color: #8fccca; padding: 2%">
+                  <span [style]="'font-size: x-large; font-weight: bolder;' + 
(item.collector.status == 0 ? 'color: green' : 'color: red')">
+                    {{
+                      item.collector.status == 0 ? 
('monitor.collector.status.online' | i18n) : 
('monitor.collector.status.offline' | i18n)
+                    }}
+                  </span>
+                </div>
+              </nz-tab>
+              <nz-tab [nzTitle]="'collector.task' | i18n">
+                <div class="rounded-lg" style="text-align: center; width: 
100%; background-color: #8fccca; padding: 2%">
+                  <span style="font-size: xxx-large; font-weight: bolder; 
color: white">
+                    {{ item.pinMonitorNum + item.dispatchMonitorNum }}
+                  </span>
+                  <br />
+                  <nz-tag style="margin-bottom: 4%; font-weight: bolder">{{ 
'collector.pinned' | i18n }}: {{ item.pinMonitorNum }}</nz-tag>
+                  <nz-tag style="margin-bottom: 4%; font-weight: bolder"
+                    >{{ 'collector.dispatched' | i18n }}: {{ 
item.dispatchMonitorNum }}</nz-tag
+                  >
+                </div>
+              </nz-tab>
+              <nz-tab [nzTitle]="'collector.start-time' | i18n">
+                <div class="rounded-lg" style="text-align: center; width: 
100%; background-color: #8fccca; padding: 2%">
+                  <span style="font-size: x-large; font-weight: bolder; color: 
white">{{
+                    (item.collector.gmtUpdate | date : 'YYYY-MM-dd 
HH:mm:ss')?.trim()
+                  }}</span>
+                </div>
+              </nz-tab>
+              <nz-tab [nzTitle]="'collector.ip' | i18n">
+                <div class="rounded-lg" style="text-align: center; width: 
100%; background-color: #8fccca; padding: 2%">
+                  <span style="font-size: x-large; font-weight: bolder; color: 
white">{{ item.collector.ip }}</span>
+                </div>
+              </nz-tab>
+              <nz-tab [nzTitle]="'collector.node' | i18n">
+                <div class="rounded-lg" style="text-align: center; width: 
100%; background-color: #8fccca; padding: 2%">
+                  <span style="font-size: x-large; font-weight: bolder; color: 
white">{{ item.collector.name }}</span>
+                </div>
+              </nz-tab>
+            </nz-tabset>
+          </nz-card-tab>
+          <ng-template #collectorCardTitle>
+            <span style="font-size: medium; font-weight: bold" nz-tooltip 
[nzTooltipTitle]="item.collector.name">
+              <span nz-icon nzType="bug" nzTheme="outline" 
style="margin-right: 4px"></span>
+              <span>{{ 'collector' | i18n }} : {{ item.collector.name }}</span>
+            </span>
+          </ng-template>
+        </nz-card>
+      </div>
+    </nz-spin>
   </div>
 </div>
 
 <div nz-row nzGutter="16" style="margin-top: 25px; height: 320px">
-  <div nz-col [nzXs]="{ span: 24 }" [nzSm]="{ span: 24 }" [nzMd]="{ span: 15 
}" class="mb-md" style="height: 100%">
-    <nz-card nzHoverable [nzTitle]="alertCardTitleTemplate" 
[nzExtra]="extraTemplate" style="height: inherit; overflow-y: scroll">
-      <nz-timeline nzMode="left">
-        <nz-timeline-item
-          *ngFor="let alert of alerts; let i = index"
-          [nzLabel]="(alert.lastAlarmTime | date : 'YYYY-MM-dd 
HH:mm:ss')?.trim()"
-        >
-          <p style="font-weight: 400">
-            <nz-tag *ngIf="alert.priority == 0" nzColor="red">
-              <i nz-icon nzType="bell" nzTheme="outline"></i>
-              <span>{{ 'alert.priority.0' | i18n }}</span>
-            </nz-tag>
-            <nz-tag *ngIf="alert.priority == 1" nzColor="orange">
-              <i nz-icon nzType="bell" nzTheme="outline"></i>
-              <span>{{ 'alert.priority.1' | i18n }}</span>
-            </nz-tag>
-            <nz-tag *ngIf="alert.priority == 2" nzColor="yellow">
-              <i nz-icon nzType="bell" nzTheme="outline"></i>
-              <span>{{ 'alert.priority.2' | i18n }}</span>
-            </nz-tag>
-            <span>[{{ alert.tags.monitorName }}] </span>
-            {{ alert.content }}
-          </p>
-        </nz-timeline-item>
-      </nz-timeline>
-    </nz-card>
+  <div nz-col [nzXs]="{ span: 24 }" [nzSm]="{ span: 24 }" [nzMd]="{ span: 15 
}" class="mb-md timeline-card" style="height: 100%">
+    <nz-spin [nzSpinning]="alertContentLoading">
+      <nz-card nzHoverable [nzTitle]="alertCardTitleTemplate" 
[nzExtra]="extraTemplate" style="height: inherit; overflow: hidden">
+        <nz-timeline nzMode="left">
+          <nz-timeline-item
+            *ngFor="let alert of alerts; let i = index"
+            [nzLabel]="(alert.lastAlarmTime | date : 'YYYY-MM-dd 
HH:mm:ss')?.trim()"
+          >
+            <p style="font-weight: 400">
+              <nz-tag *ngIf="alert.priority == 0" nzColor="red">
+                <i nz-icon nzType="bell" nzTheme="outline"></i>
+                <span>{{ 'alert.priority.0' | i18n }}</span>
+              </nz-tag>
+              <nz-tag *ngIf="alert.priority == 1" nzColor="orange">
+                <i nz-icon nzType="bell" nzTheme="outline"></i>
+                <span>{{ 'alert.priority.1' | i18n }}</span>
+              </nz-tag>
+              <nz-tag *ngIf="alert.priority == 2" nzColor="yellow">
+                <i nz-icon nzType="bell" nzTheme="outline"></i>
+                <span>{{ 'alert.priority.2' | i18n }}</span>
+              </nz-tag>
+              <span>[{{ alert.tags.monitorName }}] </span>
+              {{ alert.content }}
+            </p>
+          </nz-timeline-item>
+        </nz-timeline>
+      </nz-card>
+    </nz-spin>
   </div>
   <div nz-col [nzXs]="{ span: 24 }" [nzSm]="{ span: 12 }" [nzMd]="{ span: 9 }" 
class="mb-md" style="height: 100%">
-    <div
-      echarts
-      [options]="alertsEChartOption"
-      theme="default"
-      [autoResize]="true"
-      [loading]="alertsLoading"
-      (chartInit)="onAlertNumChartInit($event)"
-      style="width: 100%; height: inherit; padding-left: 30px"
-      class="ant-card ant-card-bordered ant-card-hoverable"
-    ></div>
+    <nz-spin [nzSpinning]="alertsLoading">
+      <div
+        echarts
+        [options]="alertsEChartOption"
+        theme="default"
+        [autoResize]="true"
+        [loading]="alertsLoading"
+        (chartInit)="onAlertNumChartInit($event)"
+        style="width: 100%; height: inherit; padding-left: 30px"
+        class="ant-card ant-card-bordered ant-card-hoverable"
+      ></div>
+    </nz-spin>
   </div>
 </div>
 
diff --git a/web-app/src/app/routes/dashboard/dashboard.component.less 
b/web-app/src/app/routes/dashboard/dashboard.component.less
index 17b7e2a49..1d2eadd30 100644
--- a/web-app/src/app/routes/dashboard/dashboard.component.less
+++ b/web-app/src/app/routes/dashboard/dashboard.component.less
@@ -42,7 +42,28 @@
   .ant-timeline-item {
     padding-bottom: 10px;
   }
+  .tag-animation-delay {
+    cursor: pointer;
   }
+  .ant-spin-nested-loading, .ant-spin-container {
+    height: 100%;
+  }
+  .timeline-card {
+    .ant-card {
+      display: flex;
+      flex-direction: column;
+      cursor: default!important;
+      .ant-card-head {
+        flex-shrink: 0;
+      }
+      .ant-card-body {
+        flex: 1;
+        overflow-y: auto;
+        margin-bottom: 12px;
+      }
+    }
+  }
+}
 
 [data-theme='dark'] {
   :host ::ng-deep {
diff --git a/web-app/src/app/routes/dashboard/dashboard.component.ts 
b/web-app/src/app/routes/dashboard/dashboard.component.ts
index c75951042..08f72c9d8 100644
--- a/web-app/src/app/routes/dashboard/dashboard.component.ts
+++ b/web-app/src/app/routes/dashboard/dashboard.component.ts
@@ -25,6 +25,7 @@ import { CloudData } from 'angular-tag-cloud-module';
 import { EChartsOption } from 'echarts';
 import { NzMessageService } from 'ng-zorro-antd/message';
 import { fromEvent } from 'rxjs';
+import { finalize } from 'rxjs/operators';
 
 import { Alert } from '../../pojo/Alert';
 import { AppCount } from '../../pojo/AppCount';
@@ -55,6 +56,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
 
   // Tag Word Cloud
   wordCloudData: CloudData[] = [];
+  wordCloudDataLoading: boolean = false;
   defaultWordCloudData: CloudData[] = [
     { text: 'HertzBeat', weight: 5 },
     { text: 'Env:Prod', weight: 8 },
@@ -77,34 +79,38 @@ export class DashboardComponent implements OnInit, 
OnDestroy {
   ];
 
   refreshWordCloudContent(): void {
-    let tagsInit$ = this.tagSvc.loadTags(undefined, 1, 0, 10000).subscribe(
-      message => {
-        if (message.code === 0) {
-          let page = message.data;
-          let tags = page.content;
-          if (tags != null && tags.length != 0) {
-            let tmpData: CloudData[] = [];
-            tags.forEach(item => {
-              tmpData.push({
-                text: formatTagName(item),
-                weight: Math.random() * (10 - 5) + 5
+    this.wordCloudDataLoading = true;
+    let tagsInit$ = this.tagSvc
+      .loadTags(undefined, 1, 0, 10000)
+      .pipe(finalize(() => (this.wordCloudDataLoading = false)))
+      .subscribe(
+        message => {
+          if (message.code === 0) {
+            let page = message.data;
+            let tags = page.content;
+            if (tags != null && tags.length != 0) {
+              let tmpData: CloudData[] = [];
+              tags.forEach(item => {
+                tmpData.push({
+                  text: formatTagName(item),
+                  weight: Math.random() * (10 - 5) + 5
+                });
               });
-            });
-            this.wordCloudData = tmpData;
+              this.wordCloudData = tmpData;
+            } else {
+              this.wordCloudData = this.defaultWordCloudData;
+            }
+            this.cdr.detectChanges();
           } else {
-            this.wordCloudData = this.defaultWordCloudData;
+            console.warn(message.msg);
           }
-          this.cdr.detectChanges();
-        } else {
-          console.warn(message.msg);
+          tagsInit$.unsubscribe();
+        },
+        error => {
+          tagsInit$.unsubscribe();
+          console.error(error.msg);
         }
-        tagsInit$.unsubscribe();
-      },
-      error => {
-        tagsInit$.unsubscribe();
-        console.error(error.msg);
-      }
-    );
+      );
   }
 
   onTagCloudClick(data: CloudData): void {
@@ -163,10 +169,12 @@ export class DashboardComponent implements OnInit, 
OnDestroy {
   pageResize$!: any;
 
   // collector list
+  collectorsLoading: boolean = false;
   collectors!: CollectorSummary[];
 
   // 告警列表
   alerts!: Alert[];
+  alertContentLoading: boolean = false;
 
   ngOnInit(): void {
     this.appsCountTheme = {
@@ -559,40 +567,48 @@ export class DashboardComponent implements OnInit, 
OnDestroy {
   alertsDealLoading: boolean = true;
 
   refreshAlertContentList(): void {
-    let alertsInit$ = this.alertSvc.loadAlerts(undefined, undefined, 
undefined, 0, 10).subscribe(
-      message => {
-        if (message.code === 0) {
-          let page = message.data;
-          this.alerts = page.content;
-          this.cdr.detectChanges();
-        } else {
-          console.warn(message.msg);
+    this.alertContentLoading = true;
+    let alertsInit$ = this.alertSvc
+      .loadAlerts(undefined, undefined, undefined, 0, 10)
+      .pipe(finalize(() => (this.alertContentLoading = false)))
+      .subscribe(
+        message => {
+          if (message.code === 0) {
+            let page = message.data;
+            this.alerts = page.content;
+            this.cdr.detectChanges();
+          } else {
+            console.warn(message.msg);
+          }
+          alertsInit$.unsubscribe();
+        },
+        error => {
+          alertsInit$.unsubscribe();
+          console.error(error.msg);
         }
-        alertsInit$.unsubscribe();
-      },
-      error => {
-        alertsInit$.unsubscribe();
-        console.error(error.msg);
-      }
-    );
+      );
   }
 
   refreshCollectorContentList(): void {
-    let collectorInit$ = this.collectorSvc.getCollectors().subscribe(
-      message => {
-        if (message.code === 0) {
-          this.collectors = message.data.content;
-          this.cdr.detectChanges();
-        } else {
-          console.warn(message.msg);
+    this.collectorsLoading = true;
+    let collectorInit$ = this.collectorSvc
+      .getCollectors()
+      .pipe(finalize(() => (this.collectorsLoading = false)))
+      .subscribe(
+        message => {
+          if (message.code === 0) {
+            this.collectors = message.data.content;
+            this.cdr.detectChanges();
+          } else {
+            console.warn(message.msg);
+          }
+          collectorInit$.unsubscribe();
+        },
+        error => {
+          collectorInit$.unsubscribe();
+          console.error(error.msg);
         }
-        collectorInit$.unsubscribe();
-      },
-      error => {
-        collectorInit$.unsubscribe();
-        console.error(error.msg);
-      }
-    );
+      );
   }
 
   refreshAlertSummary(): void {


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

Reply via email to