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

tomsun28 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 eb7ca9728d improve(dashboard): hide empty category cards, add empty 
state (#4242)
eb7ca9728d is described below

commit eb7ca9728d45574ee10eac103b0f2bd2728f89c1
Author: NekoPunch <[email protected]>
AuthorDate: Sun Jul 26 03:32:23 2026 -0700

    improve(dashboard): hide empty category cards, add empty state (#4242)
    
    Co-authored-by: Tomsun28 <[email protected]>
    Co-authored-by: aias00 <[email protected]>
---
 .../app/routes/dashboard/dashboard.component.html  | 319 ++-------------------
 .../app/routes/dashboard/dashboard.component.less  |  33 +++
 .../app/routes/dashboard/dashboard.component.ts    |  58 ++--
 web-app/src/app/routes/routes.module.ts            |   2 +
 web-app/src/assets/i18n/en-US.json                 |   2 +
 web-app/src/assets/i18n/ja-JP.json                 |   2 +
 web-app/src/assets/i18n/ko-KR.json                 |   2 +
 web-app/src/assets/i18n/pt-BR.json                 |   2 +
 web-app/src/assets/i18n/zh-CN.json                 |   2 +
 web-app/src/assets/i18n/zh-TW.json                 |   4 +-
 10 files changed, 104 insertions(+), 322 deletions(-)

diff --git a/web-app/src/app/routes/dashboard/dashboard.component.html 
b/web-app/src/app/routes/dashboard/dashboard.component.html
index fd5276d0c6..ddc816c07d 100644
--- a/web-app/src/app/routes/dashboard/dashboard.component.html
+++ b/web-app/src/app/routes/dashboard/dashboard.component.html
@@ -20,320 +20,30 @@
 <div class="mobile-hide">
   <div nz-row nzGutter="16">
     <div nz-col [nzXs]="{ span: 24 }" [nzSm]="{ span: 24 }" [nzMd]="{ span: 24 
}" style="height: 100%">
-      <ngx-slick-carousel nz-row class="carousel" [config]="slideConfig">
-        <div style="width: 25%; margin: 3px" ngxSlickItem class="slide">
+      <ngx-slick-carousel nz-row class="carousel" [config]="slideConfig" 
*ngIf="categoryCards.length > 0">
+        <div style="width: 25%; margin: 3px" ngxSlickItem class="slide" 
*ngFor="let card of categoryCards">
           <div class="hoverCard">
             <div nz-row nzAlign="middle" class="bg-primary dashboard-rounded">
               <div nz-col nzSpan="9" class="p-md text-white">
-                <div class="h2 mt0 font-weight-bold">{{ appCountService.size 
}}</div>
+                <div class="h2 mt0 font-weight-bold">{{ card.count.size 
}}</div>
                 <p class="h5 text-nowrap mb0">
-                  <i nz-icon nzType="cloud" nzTheme="outline"></i>
-                  {{ 'monitor.category.service' | i18n }}
+                  <i nz-icon [nzType]="card.icon" nzTheme="outline"></i>
+                  {{ 'monitor.category.' + card.category | i18n }}
                 </p>
               </div>
               <div nz-col nzSpan="15">
                 <div class="dashboard-slider-tag">
                   <nz-tag [nzBordered]="false" class="mb-xs">
                     <span>{{ 'monitor.status.up' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountService.availableSize }}</span>
+                    <span style="font-weight: bolder">{{ 
card.count.availableSize }}</span>
                   </nz-tag>
                   <nz-tag [nzBordered]="false" class="mb-xs">
                     <span>{{ 'monitor.status.down' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountService.unAvailableSize }}</span>
+                    <span style="font-weight: bolder">{{ 
card.count.unAvailableSize }}</span>
                   </nz-tag>
                   <nz-tag [nzBordered]="false" class="mb-xs">
                     <span>{{ 'monitor.status.paused' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountService.unManageSize }}</span>
-                  </nz-tag>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div style="width: 25%; margin: 3px" ngxSlickItem class="slide">
-          <div class="hoverCard">
-            <div nz-row nzAlign="middle" class="bg-primary dashboard-rounded">
-              <div nz-col nzSpan="9" class="p-md text-white">
-                <div class="h2 mt0 font-weight-bold">{{ appCountProgram.size 
}}</div>
-                <p class="h5 text-nowrap mb0">
-                  <i nz-icon nzType="code" nzTheme="outline"></i>
-                  {{ 'monitor.category.program' | i18n }}
-                </p>
-              </div>
-              <div nz-col nzSpan="15">
-                <div class="dashboard-slider-tag">
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.up' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountProgram.availableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.down' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountProgram.unAvailableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.paused' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountProgram.unManageSize }}</span>
-                  </nz-tag>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div style="width: 25%; margin: 3px" ngxSlickItem class="slide">
-          <div class="hoverCard">
-            <div nz-row nzAlign="middle" class="bg-primary dashboard-rounded">
-              <div nz-col nzSpan="9" class="p-md text-white">
-                <div class="h2 mt0 font-weight-bold">{{ appCountDb.size 
}}</div>
-                <p class="h5 text-nowrap mb0">
-                  <i nz-icon nzType="database" nzTheme="outline"></i>
-                  {{ 'monitor.category.db' | i18n }}
-                </p>
-              </div>
-              <div nz-col nzSpan="15">
-                <div class="dashboard-slider-tag">
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.up' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountDb.availableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.down' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountDb.unAvailableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.paused' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountDb.unManageSize }}</span>
-                  </nz-tag>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div style="width: 25%; margin: 3px" ngxSlickItem class="slide">
-          <div class="hoverCard">
-            <div nz-row nzAlign="middle" class="bg-primary dashboard-rounded">
-              <div nz-col nzSpan="9" class="p-md text-white">
-                <div class="h2 mt0 font-weight-bold">{{ appCountCache.size 
}}</div>
-                <p class="h5 text-nowrap mb0">
-                  <i nz-icon nzType="group" nzTheme="outline"></i>
-                  {{ 'monitor.category.cache' | i18n }}
-                </p>
-              </div>
-              <div nz-col nzSpan="15">
-                <div class="dashboard-slider-tag">
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.up' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountCache.availableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.down' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountCache.unAvailableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.paused' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountCache.unManageSize }}</span>
-                  </nz-tag>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div style="width: 25%; margin: 3px" ngxSlickItem class="slide">
-          <div class="hoverCard">
-            <div nz-row nzAlign="middle" class="bg-primary dashboard-rounded">
-              <div nz-col nzSpan="9" class="p-md text-white">
-                <div class="h2 mt0 font-weight-bold">{{ appCountOs.size 
}}</div>
-                <p class="h5 text-nowrap mb0">
-                  <i nz-icon nzType="windows" nzTheme="outline"></i>
-                  {{ 'monitor.category.os' | i18n }}
-                </p>
-              </div>
-              <div nz-col nzSpan="15">
-                <div class="dashboard-slider-tag">
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.up' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountOs.availableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.down' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountOs.unAvailableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.paused' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountOs.unManageSize }}</span>
-                  </nz-tag>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div style="width: 25%; margin: 3px" ngxSlickItem class="slide">
-          <div class="hoverCard">
-            <div nz-row nzAlign="middle" class="bg-primary dashboard-rounded">
-              <div nz-col nzSpan="9" class="p-md text-white">
-                <div class="h2 mt0 font-weight-bold">{{ appCountMid.size 
}}</div>
-                <p class="h5 text-nowrap mb0">
-                  <i nz-icon nzType="merge-cells" nzTheme="outline"></i>
-                  {{ 'monitor.category.mid' | i18n }}
-                </p>
-              </div>
-              <div nz-col nzSpan="15">
-                <div class="dashboard-slider-tag">
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.up' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountMid.availableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.down' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountMid.unAvailableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.paused' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountMid.unManageSize }}</span>
-                  </nz-tag>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div style="width: 25%; margin: 3px" ngxSlickItem class="slide">
-          <div class="hoverCard">
-            <div nz-row nzAlign="middle" class="bg-primary dashboard-rounded">
-              <div nz-col nzSpan="9" class="p-md text-white">
-                <div class="h2 mt0 font-weight-bold">{{ appCountBigdata.size 
}}</div>
-                <p class="h5 text-nowrap mb0">
-                  <i nz-icon nzType="dot-chart" nzTheme="outline"></i>
-                  {{ 'monitor.category.bigdata' | i18n }}
-                </p>
-              </div>
-              <div nz-col nzSpan="15">
-                <div class="dashboard-slider-tag">
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.up' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountBigdata.availableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.down' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountBigdata.unAvailableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.paused' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountBigdata.unManageSize }}</span>
-                  </nz-tag>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div style="width: 25%; margin: 3px" ngxSlickItem class="slide">
-          <div class="hoverCard">
-            <div nz-row nzAlign="middle" class="bg-primary dashboard-rounded">
-              <div nz-col nzSpan="9" class="p-md text-white">
-                <div class="h2 mt0 font-weight-bold">{{ appCountWebserver.size 
}}</div>
-                <p class="h5 text-nowrap mb0">
-                  <i nz-icon nzType="database" nzTheme="outline"></i>
-                  {{ 'monitor.category.webserver' | i18n }}
-                </p>
-              </div>
-              <div nz-col nzSpan="15">
-                <div class="dashboard-slider-tag">
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.up' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountWebserver.availableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.down' | i18n }} </span
-                    ><span style="font-weight: bolder">{{ 
appCountWebserver.unAvailableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.paused' | i18n }} </span
-                    ><span style="font-weight: bolder">{{ 
appCountWebserver.unManageSize }}</span>
-                  </nz-tag>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div style="width: 25%; margin: 3px" ngxSlickItem class="slide">
-          <div class="hoverCard">
-            <div nz-row nzAlign="middle" class="bg-primary dashboard-rounded">
-              <div nz-col nzSpan="9" class="p-md text-white">
-                <div class="h2 mt0 font-weight-bold">{{ appCountCn.size 
}}</div>
-                <p class="h5 text-nowrap mb0">
-                  <i nz-icon nzType="cloud-server" nzTheme="outline"></i>
-                  {{ 'monitor.category.cn' | i18n }}
-                </p>
-              </div>
-              <div nz-col nzSpan="15">
-                <div class="dashboard-slider-tag">
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.up' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountCn.availableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.down' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountCn.unAvailableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.paused' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountCn.unManageSize }}</span>
-                  </nz-tag>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div style="width: 25%; margin: 3px" ngxSlickItem class="slide">
-          <div class="hoverCard">
-            <div nz-row nzAlign="middle" class="bg-primary dashboard-rounded">
-              <div nz-col nzSpan="9" class="p-md text-white">
-                <div class="h2 mt0 font-weight-bold">{{ appCountNetwork.size 
}}</div>
-                <p class="h5 text-nowrap mb0">
-                  <i nz-icon nzType="global" nzTheme="outline"></i>
-                  {{ 'monitor.category.network' | i18n }}
-                </p>
-              </div>
-              <div nz-col nzSpan="15">
-                <div class="dashboard-slider-tag">
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.up' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountNetwork.availableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.down' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountNetwork.unAvailableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.paused' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountNetwork.unManageSize }}</span>
-                  </nz-tag>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div style="width: 25%; margin: 3px" ngxSlickItem class="slide">
-          <div class="hoverCard">
-            <div nz-row nzAlign="middle" class="bg-primary dashboard-rounded">
-              <div nz-col nzSpan="9" class="p-md text-white">
-                <div class="h2 mt0 font-weight-bold">{{ appCountCustom.size 
}}</div>
-                <p class="h5 text-nowrap mb0">
-                  <i nz-icon nzType="project" nzTheme="outline"></i>
-                  {{ 'monitor.category.custom' | i18n }}
-                </p>
-              </div>
-              <div nz-col nzSpan="15">
-                <div class="dashboard-slider-tag">
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.up' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountCustom.availableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.down' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountCustom.unAvailableSize }}</span>
-                  </nz-tag>
-                  <nz-tag [nzBordered]="false" class="mb-xs">
-                    <span>{{ 'monitor.status.paused' | i18n }} </span>
-                    <span style="font-weight: bolder">{{ 
appCountCustom.unManageSize }}</span>
+                    <span style="font-weight: bolder">{{ 
card.count.unManageSize }}</span>
                   </nz-tag>
                 </div>
               </div>
@@ -341,6 +51,19 @@
           </div>
         </div>
       </ngx-slick-carousel>
+      <div *ngIf="!appsCountLoading && totalMonitors === 0" 
class="dashboard-empty-state">
+        <nz-empty [nzNotFoundContent]="emptyContent" 
[nzNotFoundFooter]="emptyFooter">
+          <ng-template #emptyContent>
+            <div class="empty-title">{{ 'dashboard.monitors.empty' | i18n 
}}</div>
+          </ng-template>
+          <ng-template #emptyFooter>
+            <button nz-button nzType="primary" nzSize="large" 
class="empty-add-btn" routerLink="/monitors/new">
+              <i nz-icon nzType="plus" nzTheme="outline"></i>
+              {{ 'dashboard.monitors.add' | i18n }}
+            </button>
+          </ng-template>
+        </nz-empty>
+      </div>
     </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 7fcf40d15d..4fed13285c 100644
--- a/web-app/src/app/routes/dashboard/dashboard.component.less
+++ b/web-app/src/app/routes/dashboard/dashboard.component.less
@@ -155,3 +155,36 @@
     transition: 0.2s;
   }
 }
+
+.dashboard-empty-state {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 20px 16px;
+
+  ::ng-deep .ant-empty-image {
+    height: 80px;
+  }
+
+  .empty-title {
+    margin-top: 2px;
+    font-size: 16px;
+    font-weight: 600;
+    color: @heading-color;
+  }
+
+  .empty-add-btn {
+    margin-top: 14px;
+    height: 38px;
+    padding: 0 24px;
+    font-size: 14px;
+    border-radius: 19px;
+    box-shadow: 0 4px 12px fade(@primary-color, 30%);
+    transition: transform 0.25s, box-shadow 0.25s;
+
+    &:hover {
+      transform: translateY(-2px);
+      box-shadow: 0 6px 16px fade(@primary-color, 40%);
+    }
+  }
+}
diff --git a/web-app/src/app/routes/dashboard/dashboard.component.ts 
b/web-app/src/app/routes/dashboard/dashboard.component.ts
index b4b20fc400..1e71dce3ca 100644
--- a/web-app/src/app/routes/dashboard/dashboard.component.ts
+++ b/web-app/src/app/routes/dashboard/dashboard.component.ts
@@ -37,6 +37,17 @@ import { MonitorService } from 
'../../service/monitor.service';
 import { ThemeService } from '../../service/theme.service';
 import { formatLabelName } from '../../shared/utils/common-util';
 
+interface SlideConfig {
+  infinite: boolean;
+  speed: number;
+  slidesToShow: number;
+  slidesToScroll: number;
+  autoplay: boolean;
+  autoplaySpeed: number;
+  rows: number;
+  responsive: Array<{ breakpoint: number; settings: Record<string, number | 
boolean> }>;
+}
+
 @Component({
   selector: 'app-dashboard',
   templateUrl: './dashboard.component.html',
@@ -121,19 +132,10 @@ export class DashboardComponent implements OnInit, 
OnDestroy {
   }
 
   // start -- quantitative information summary
-  appCountService: AppCount = new AppCount();
-  appCountOs: AppCount = new AppCount();
-  appCountDb: AppCount = new AppCount();
-  appCountMid: AppCount = new AppCount();
-  appCountCustom: AppCount = new AppCount();
-  appCountProgram: AppCount = new AppCount();
-  appCountCache: AppCount = new AppCount();
-  appCountBigdata: AppCount = new AppCount();
-  appCountWebserver: AppCount = new AppCount();
-  appCountCn: AppCount = new AppCount();
-  appCountNetwork: AppCount = new AppCount();
+  categoryCards: Array<{ category: string; icon: string; count: AppCount }> = 
[];
+  totalMonitors: number = 0;
 
-  slideConfig = {
+  slideConfig: SlideConfig = {
     infinite: true,
     speed: 1800,
     slidesToShow: 4,
@@ -495,17 +497,27 @@ export class DashboardComponent implements OnInit, 
OnDestroy {
                 break;
             }
           });
-          this.appCountService = appCountService;
-          this.appCountOs = appCountOs;
-          this.appCountDb = appCountDb;
-          this.appCountMid = appCountMid;
-          this.appCountCustom = appCountCustom;
-          this.appCountBigdata = appCountBigdata;
-          this.appCountCache = appCountCache;
-          this.appCountProgram = appCountProgram;
-          this.appCountWebserver = appCountWebserver;
-          this.appCountNetwork = appCountNetwork;
-          this.appCountCn = appCountCn;
+          this.totalMonitors = total;
+          this.categoryCards = [
+            { category: 'service', icon: 'cloud', count: appCountService },
+            { category: 'program', icon: 'code', count: appCountProgram },
+            { category: 'db', icon: 'database', count: appCountDb },
+            { category: 'cache', icon: 'group', count: appCountCache },
+            { category: 'os', icon: 'windows', count: appCountOs },
+            { category: 'mid', icon: 'merge-cells', count: appCountMid },
+            { category: 'bigdata', icon: 'dot-chart', count: appCountBigdata },
+            { category: 'webserver', icon: 'database', count: 
appCountWebserver },
+            { category: 'cn', icon: 'cloud-server', count: appCountCn },
+            { category: 'network', icon: 'global', count: appCountNetwork },
+            { category: 'custom', icon: 'project', count: appCountCustom }
+          ].filter(card => card.count.size > 0);
+          const loop = this.categoryCards.length > 
this.slideConfig.slidesToShow;
+          this.slideConfig = {
+            ...this.slideConfig,
+            infinite: loop,
+            autoplay: loop,
+            responsive: this.slideConfig.responsive.map(r => ({ ...r, 
settings: { ...r.settings, infinite: loop } }))
+          };
           // @ts-ignore
           this.appsCountTheme.series[0].data = [{ value: total, name: 
this.i18nSvc.fanyi('dashboard.monitors.total') }];
           // @ts-ignore
diff --git a/web-app/src/app/routes/routes.module.ts 
b/web-app/src/app/routes/routes.module.ts
index 37999b486b..ade9f4991c 100644
--- a/web-app/src/app/routes/routes.module.ts
+++ b/web-app/src/app/routes/routes.module.ts
@@ -7,6 +7,7 @@ import { TagCloudComponent } from 'angular-tag-cloud-module';
 import { NzCascaderModule } from 'ng-zorro-antd/cascader';
 import { NzCollapseModule } from 'ng-zorro-antd/collapse';
 import { NzDividerModule } from 'ng-zorro-antd/divider';
+import { NzEmptyModule } from 'ng-zorro-antd/empty';
 import { NzListModule } from 'ng-zorro-antd/list';
 import { NzRadioModule } from 'ng-zorro-antd/radio';
 import { NzSwitchComponent } from 'ng-zorro-antd/switch';
@@ -38,6 +39,7 @@ const COMPONENTS: Array<Type<void>> = [DashboardComponent, 
UserLoginComponent, U
     SlickCarouselModule,
     TagCloudComponent,
     NzDividerModule,
+    NzEmptyModule,
     LayoutModule,
     NzCollapseModule,
     NzListModule,
diff --git a/web-app/src/assets/i18n/en-US.json 
b/web-app/src/assets/i18n/en-US.json
index 1c4cc97836..369ca6600a 100644
--- a/web-app/src/assets/i18n/en-US.json
+++ b/web-app/src/assets/i18n/en-US.json
@@ -589,6 +589,8 @@
   "dashboard.monitors.sub-title": "The Distribution Of Monitors",
   "dashboard.monitors.title": "Monitoring Overview",
   "dashboard.monitors.total": "Monitor Total",
+  "dashboard.monitors.empty": "No monitors yet",
+  "dashboard.monitors.add": "Add Monitor",
   "define.delete": "Delete {{app}}",
   "define.delete.confirm": "Please confirm whether to delete {{app}} 
monitoring type? This type of monitoring cannot be added after deletion.",
   "define.disable": "Disable {{app}}",
diff --git a/web-app/src/assets/i18n/ja-JP.json 
b/web-app/src/assets/i18n/ja-JP.json
index e641b6252b..41f9776a82 100644
--- a/web-app/src/assets/i18n/ja-JP.json
+++ b/web-app/src/assets/i18n/ja-JP.json
@@ -549,6 +549,8 @@
   "dashboard.monitors.sub-title": "モニターの分布",
   "dashboard.monitors.title": "監視概要",
   "dashboard.monitors.total": "モニター総数",
+  "dashboard.monitors.empty": "監視タスクはまだありません",
+  "dashboard.monitors.add": "監視を追加",
   "define.delete": "{{app}}を削除",
   "define.delete.confirm": 
"{{app}}監視タイプを削除してもよろしいですか?削除後、このタイプの監視を追加できなくなります。",
   "define.disable": "{{app}}を無効化",
diff --git a/web-app/src/assets/i18n/ko-KR.json 
b/web-app/src/assets/i18n/ko-KR.json
index 67764807e8..23145f738b 100644
--- a/web-app/src/assets/i18n/ko-KR.json
+++ b/web-app/src/assets/i18n/ko-KR.json
@@ -585,6 +585,8 @@
   "dashboard.monitors.sub-title": "모니터링 분포 현황",
   "dashboard.monitors.title": "모니터링 개요",
   "dashboard.monitors.total": "전체 모니터링 수",
+  "dashboard.monitors.empty": "모니터링 작업이 없습니다",
+  "dashboard.monitors.add": "모니터링 추가",
   "define.delete": "{{app}} 삭제",
   "define.delete.confirm": "{{app}} 모니터링 유형을 삭제하시겠습니까? 삭제 후에는 이 유형의 모니터링을 추가할 
수 없습니다.",
   "define.disable": "{{app}} 비활성화",
diff --git a/web-app/src/assets/i18n/pt-BR.json 
b/web-app/src/assets/i18n/pt-BR.json
index d2e92d6230..e089b95d53 100644
--- a/web-app/src/assets/i18n/pt-BR.json
+++ b/web-app/src/assets/i18n/pt-BR.json
@@ -345,6 +345,8 @@
   "dashboard.alerts.deal": "Tratamento de Alarmes",
   "dashboard.alerts.deal-percent": "Taxa de Tratamento",
   "dashboard.monitors.total": "Total de Monitores",
+  "dashboard.monitors.empty": "Nenhum monitor ainda",
+  "dashboard.monitors.add": "Adicionar Monitor",
   "dashboard.monitors.title": "Visão Geral do Monitoramento",
   "dashboard.monitors.sub-title": "A Distribuição dos Monitores",
   "dashboard.monitors.formatter": " Monitores ",
diff --git a/web-app/src/assets/i18n/zh-CN.json 
b/web-app/src/assets/i18n/zh-CN.json
index d0b49fc070..d6397daa0f 100644
--- a/web-app/src/assets/i18n/zh-CN.json
+++ b/web-app/src/assets/i18n/zh-CN.json
@@ -592,6 +592,8 @@
   "dashboard.monitors.sub-title": "监控类型纳管数量分布",
   "dashboard.monitors.title": "监控总览",
   "dashboard.monitors.total": "监控总量",
+  "dashboard.monitors.empty": "暂无监控任务",
+  "dashboard.monitors.add": "添加监控",
   "define.delete": "删除 {{app}}",
   "define.delete.confirm": "请确认是否删除 {{app}} 监控类型? 删除后无法添加此类监控。",
   "define.disable": "禁用 {{app}}",
diff --git a/web-app/src/assets/i18n/zh-TW.json 
b/web-app/src/assets/i18n/zh-TW.json
index fc76f38dd2..4cdbf1d2be 100644
--- a/web-app/src/assets/i18n/zh-TW.json
+++ b/web-app/src/assets/i18n/zh-TW.json
@@ -553,6 +553,8 @@
   "dashboard.monitors.sub-title": "監控類型納管數量分布",
   "dashboard.monitors.title": "監控總覽",
   "dashboard.monitors.total": "監控總量",
+  "dashboard.monitors.empty": "暫無監控任務",
+  "dashboard.monitors.add": "新增監控",
   "define.delete": "刪除 {{app}}",
   "define.delete.confirm": "請確認是否刪除 {{app}} 監控類型? 刪除後無法添加此類監控。",
   "define.disable": "禁用 {{app}}",
@@ -1206,7 +1208,7 @@
   "ai.chat.security.form.complete": "完成",
   "ai.chat.security.form.default.callback": "表單已完成",
   "ai.chat.config.participation.model": "AI參與模式",
-   "ai.chat.config.participation.model.help": 
"信任模式:所有的資料都會傳送到大模型處理,受保護模式:限制一些AI能力,如私密資料不傳送給大模型處理",
+  "ai.chat.config.participation.model.help": 
"信任模式:所有的資料都會傳送到大模型處理,受保護模式:限制一些AI能力,如私密資料不傳送給大模型處理",
   "ai.chat.config.participation.model.protected": "受保護模式",
   "ai.chat.config.participation.model.trusted": "信任模式",
   "setting.drawer.theme.color": "主題色",


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

Reply via email to