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

gongchao pushed a commit to branch update-monitor-list
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git

commit d356633e69bf2c667b8259851372f596b03c43ac
Author: tomsun28 <[email protected]>
AuthorDate: Mon Mar 31 13:55:06 2025 +0800

    update
---
 .../monitor-list/monitor-list.component.html       | 232 ++++++++++-----------
 .../monitor-list/monitor-list.component.less       | 184 +++++++++++++++-
 .../monitor/monitor-list/monitor-list.component.ts |  24 +--
 web-app/src/app/routes/monitor/monitor.module.ts   |   4 +-
 4 files changed, 297 insertions(+), 147 deletions(-)

diff --git 
a/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.html 
b/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.html
index 8c8fc58442..5a9ee6074a 100644
--- a/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.html
+++ b/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.html
@@ -85,12 +85,6 @@
             </button>
           </nz-upload>
         </li>
-        <li nz-menu-item>
-          <button nz-button (click)="copyMonitor()">
-            <i nz-icon nzType="copy" nzTheme="outline"></i>
-            {{ 'monitor.copy' | i18n }}
-          </button>
-        </li>
       </ul>
     </nz-dropdown-menu>
   </ng-template>
@@ -139,139 +133,131 @@
   </ng-template>
 </app-toolbar>
 
-<nz-table
-  #fixedTable
-  [nzData]="monitors"
-  [nzPageIndex]="pageIndex"
-  [nzPageSize]="pageSize"
-  [nzTotal]="total"
-  nzFrontPagination="false"
-  [nzLoading]="tableLoading"
-  nzShowSizeChanger
-  [nzShowTotal]="rangeTemplate"
-  [nzPageSizeOptions]="[8, 15, 25]"
-  (nzQueryParams)="onTablePageChange($event)"
-  nzShowPagination="true"
-  [nzScroll]="{ x: '1240px' }"
->
-  <thead>
-    <tr>
-      <th nzAlign="center" nzLeft nzWidth="3%" [(nzChecked)]="checkedAll" 
(nzCheckedChange)="onAllChecked($event)"></th>
-      <th nzAlign="center" nzWidth="20%" nzColumnKey="name" 
[nzSortFn]="true">{{ 'monitor.name' | i18n }}</th>
-      <th nzAlign="center" nzWidth="10%" nzColumnKey="status" 
[nzSortFn]="true">{{ 'monitor.status' | i18n }}</th>
-      <th nzAlign="center" nzWidth="12%">{{ 'monitor.host' | i18n }}</th>
-      <th nzAlign="center" nzWidth="10%">{{ 'monitor.app' | i18n }}</th>
-      <th nzAlign="center" nzWidth="21%">{{ 'label' | i18n }}</th>
-      <th nzAlign="center" nzWidth="14%" nzColumnKey="gmtUpdate" 
[nzSortFn]="true">{{ 'common.edit-time' | i18n }}</th>
-      <th nzAlign="center" nzWidth="10%" nzRight>{{ 'common.edit' | i18n 
}}</th>
-    </tr>
-  </thead>
-  <tbody>
-    <tr *ngFor="let data of fixedTable.data">
-      <td nzAlign="center" nzLeft [nzChecked]="checkedMonitorIds.has(data.id)" 
(nzCheckedChange)="onItemChecked(data.id, $event)"></td>
-      <td nzAlign="center" nzEllipsis>
-        <button nz-button nzSize="default" nzType="link" 
[routerLink]="['/monitors/' + data.id]">
-          {{ data.name }}
-          <span nz-icon nzType="area-chart"></span>
-        </button>
-      </td>
-      <td nzAlign="center">
-        <nz-tag *ngIf="data.status == 0" [nzColor]="'#b2b2b2'">
-          <i nz-icon nzType="meh" nzTheme="outline"></i>
-          <span>{{ 'monitor.status.paused' | i18n }}</span>
-        </nz-tag>
-        <nz-tag *ngIf="data.status == 1" [nzColor]="'#498765'">
-          <i nz-icon nzType="smile" nzTheme="outline"></i>
-          <span>{{ 'monitor.status.up' | i18n }}</span>
-        </nz-tag>
-        <nz-tag *ngIf="data.status == 2" [nzColor]="'#fd4357'">
-          <i nz-icon nzType="frown" nzTheme="outline"></i>
-          <span>{{ 'monitor.status.down' | i18n }}</span>
-        </nz-tag>
-      </td>
-      <td nzAlign="center" nzEllipsis>
-        <button
-          nz-button
-          nzSize="default"
-          nzType="text"
-          [cdkCopyToClipboard]="data.host"
-          nz-tooltip
-          [nzTooltipTitle]="'common.button.copy.tip' | i18n"
-          (click)="notifyCopySuccess()"
-        >
-          {{ data.host }}
-          <span nz-icon nzType="copy"></span>
-        </button>
-      </td>
-      <td nzAlign="center">
-        <a routerLink="/monitors" [queryParams]="{ app: data.app }">
-          <nz-tag nzColor="processing" class="hoverClass">
-            <i nz-icon nzType="cloud"></i>
-            <span>{{ 'monitor.app.' + data.app | i18n }}</span>
-          </nz-tag>
-        </a>
-      </td>
-      <td nzAlign="left">
-        <nz-tag *ngFor="let label of data.labels | keyvalue" 
style="margin-top: 2px" [nzColor]="getLabelColor(label.key)">
-          {{ label.key }}:{{ label.value }}
-        </nz-tag>
-      </td>
-      <td nzAlign="center">{{ (data.gmtUpdate ? data.gmtUpdate : 
data.gmtCreate) | date : 'YYYY-MM-dd HH:mm:ss' }}</td>
-      <td nzAlign="center" nzRight>
-        <div class="actions">
-          <button nz-button nzType="primary" [routerLink]="['/monitors/' + 
data.id]" nz-tooltip [nzTooltipTitle]="'monitor.detail' | i18n">
-            <i nz-icon nzType="area-chart" nzTheme="outline"></i>
-          </button>
-          <button nz-button nz-dropdown [nzDropdownMenu]="more_menu">
-            <span nz-icon nzType="ellipsis"></span>
-          </button>
-          <nz-dropdown-menu #more_menu="nzDropdownMenu">
+<div class="monitor-card-list">
+  <div class="monitor-list-header">
+    <div class="monitor-header-actions">
+      <label nz-checkbox [(ngModel)]="checkedAll" 
(ngModelChange)="onAllChecked($event)"></label>
+      <nz-pagination [(nzPageIndex)]="pageIndex" [nzTotal]="total" 
(nzPageIndexChange)="onPageIndexChange($event)" nzSimple></nz-pagination>
+    </div>
+  </div>
+
+  <nz-spin [nzSpinning]="tableLoading">
+    <div class="monitor-card-list-content">
+      <div class="monitor-card" *ngFor="let data of monitors">
+        <div class="monitor-card-checkbox">
+          <label nz-checkbox [ngModel]="checkedMonitorIds.has(data.id)" 
(ngModelChange)="onItemChecked(data.id, $event)"></label>
+        </div>
+        <div class="monitor-card-content">
+          <div class="monitor-card-header">
+            <div class="monitor-card-title">
+              <button nz-button nzType="link" [routerLink]="['/monitors/' + 
data.id]">
+                {{ data.name }}
+                <span nz-icon nzType="area-chart"></span>
+              </button>
+            </div>
+            <div class="monitor-card-status">
+              <nz-tag *ngIf="data.status == 0" [nzColor]="'#b2b2b2'">
+                <i nz-icon nzType="meh" nzTheme="outline"></i>
+                <span>{{ 'monitor.status.paused' | i18n }}</span>
+              </nz-tag>
+              <nz-tag *ngIf="data.status == 1" [nzColor]="'#498765'">
+                <i nz-icon nzType="smile" nzTheme="outline"></i>
+                <span>{{ 'monitor.status.up' | i18n }}</span>
+              </nz-tag>
+              <nz-tag *ngIf="data.status == 2" [nzColor]="'#fd4357'">
+                <i nz-icon nzType="frown" nzTheme="outline"></i>
+                <span>{{ 'monitor.status.down' | i18n }}</span>
+              </nz-tag>
+            </div>
+          </div>
+
+          <div class="monitor-card-info">
+            <div class="monitor-card-info-item host-item">
+              <button
+                nz-button
+                nzType="text"
+                [cdkCopyToClipboard]="data.host"
+                nz-tooltip
+                [nzTooltipTitle]="'common.button.copy.tip' | i18n"
+                (click)="notifyCopySuccess()"
+              >
+                <i nz-icon nzType="global"></i>
+                {{ data.host }}
+              </button>
+
+              <button nz-button nz-dropdown [nzDropdownMenu]="actionMenu" 
class="action-button">
+                <i nz-icon nzType="ellipsis"></i>
+              </button>
+            </div>
+
+            <div class="monitor-card-info-item meta-row">
+              <a routerLink="/monitors" [queryParams]="{ app: data.app }">
+                <nz-tag nzColor="processing">
+                  <i nz-icon nzType="cloud"></i>
+                  <span>{{ 'monitor.app.' + data.app | i18n }}</span>
+                </nz-tag>
+              </a>
+
+              <div class="label-tags">
+                <nz-tag *ngFor="let label of data.labels | keyvalue" 
[nzColor]="getLabelColor(label.key)">
+                  {{ label.key }}:{{ label.value }}
+                </nz-tag>
+              </div>
+
+              <span class="time-ago">
+                <i nz-icon nzType="clock-circle"></i>
+                {{ (data.gmtUpdate ? data.gmtUpdate : data.gmtCreate) | 
elapsedTime }}
+              </span>
+            </div>
+          </div>
+
+          <nz-dropdown-menu #actionMenu="nzDropdownMenu">
             <ul nz-menu>
               <li nz-menu-item>
-                <button nz-button (click)="onEditOneMonitor(data.id)" 
nz-tooltip [nzTooltipTitle]="'monitor.edit-monitor' | i18n">
-                  <i nz-icon nzType="edit" nzTheme="outline"></i>
+                <button nz-button [routerLink]="['/monitors/' + data.id]">
+                  <i nz-icon nzType="area-chart"></i>
+                  {{ 'monitor.detail' | i18n }}
                 </button>
               </li>
               <li nz-menu-item>
-                <button
-                  *ngIf="data.status == 0"
-                  nz-button
-                  (click)="onEnableManageOneMonitor(data.id)"
-                  nz-tooltip
-                  [nzTooltipTitle]="'monitor.enable' | i18n"
-                >
-                  <i nz-icon nzType="play-circle" nzTheme="outline"></i>
+                <button nz-button (click)="onEditOneMonitor(data.id)">
+                  <i nz-icon nzType="edit"></i>
+                  {{ 'monitor.edit-monitor' | i18n }}
                 </button>
               </li>
               <li nz-menu-item>
-                <button
-                  *ngIf="data.status != 0"
-                  nz-button
-                  (click)="onCancelManageOneMonitor(data.id)"
-                  nz-tooltip
-                  [nzTooltipTitle]="'monitor.cancel' | i18n"
-                >
-                  <i nz-icon nzType="pause-circle" nzTheme="outline"></i>
+                <button nz-button (click)="copyMonitor(data.id)">
+                  <i nz-icon nzType="copy"></i>
+                  {{ 'monitor.copy' | i18n }}
                 </button>
               </li>
+              <li nz-menu-divider></li>
+              <li nz-menu-item *ngIf="data.status == 0">
+                <button nz-button (click)="onEnableManageOneMonitor(data.id)">
+                  <i nz-icon nzType="play-circle"></i>
+                  {{ 'monitor.enable' | i18n }}
+                </button>
+              </li>
+              <li nz-menu-item *ngIf="data.status != 0">
+                <button nz-button (click)="onCancelManageOneMonitor(data.id)">
+                  <i nz-icon nzType="pause-circle"></i>
+                  {{ 'monitor.cancel' | i18n }}
+                </button>
+              </li>
+              <li nz-menu-divider></li>
               <li nz-menu-item>
-                <button
-                  nz-button
-                  nzDanger
-                  (click)="onDeleteOneMonitor(data.id)"
-                  nz-tooltip
-                  [nzTooltipTitle]="'monitor.delete-monitor' | i18n"
-                >
-                  <i nz-icon nzType="delete" nzTheme="outline"></i>
+                <button nz-button nzDanger 
(click)="onDeleteOneMonitor(data.id)">
+                  <i nz-icon nzType="delete"></i>
+                  {{ 'monitor.delete-monitor' | i18n }}
                 </button>
               </li>
             </ul>
           </nz-dropdown-menu>
         </div>
-      </td>
-    </tr>
-  </tbody>
-</nz-table>
+      </div>
+    </div>
+  </nz-spin>
+</div>
 
 <ng-template #rangeTemplate> {{ 'common.total' | i18n }} {{ total }} 
</ng-template>
 
diff --git 
a/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.less 
b/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.less
index 2f692a2575..9d4f400357 100644
--- a/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.less
+++ b/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.less
@@ -1,4 +1,5 @@
-@import '@delon/theme/index';
+@import "~src/styles/theme";
+
 ::ng-deep {
   .monitor-select-menu-modal {
     .ant-spin-container {
@@ -64,3 +65,184 @@
   opacity: 0.7;
   cursor: not-allowed;
 }
+
+.monitor-card-list {
+  width: 100%;
+  position: relative;
+}
+
+.monitor-list-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-bottom: 16px;
+  padding: 8px 0;
+  flex-wrap: wrap;
+  gap: 8px;
+}
+
+.monitor-header-actions {
+  display: flex;
+  align-items: center;
+}
+
+.monitor-card-list-content {
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+}
+
+.monitor-card {
+  display: flex;
+  width: 100%;
+  border: 1px solid #e8e8e8;
+  border-radius: 8px;
+  padding: 12px;
+  transition: all 0.3s;
+  background-color: #fff;
+  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
+}
+
+.monitor-card:hover {
+  border-color: @primary-color;
+  box-shadow: 0 1px 8px rgba(24, 144, 255, 0.2);
+  transform: translateY(-2px);
+}
+
+.monitor-card-checkbox {
+  padding-right: 16px;
+  display: flex;
+  align-items: center;
+}
+
+.monitor-card-content {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+}
+
+.monitor-card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12px;
+}
+
+.monitor-card-title {
+  font-size: 16px;
+  font-weight: 500;
+}
+
+.monitor-card-title button {
+  padding: 0;
+  height: auto;
+  font-size: 16px;
+  font-weight: 500;
+  color: @primary-color;
+}
+
+.monitor-card-info {
+  display: grid;
+  grid-template-columns: 1fr;
+  grid-gap: 8px;
+}
+
+.monitor-card-info-item {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+}
+
+.host-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  
+  button {
+    padding: 0;
+    height: auto;
+    
+    i {
+      margin-right: 4px;
+    }
+  }
+  
+  .action-button {
+    height: 32px;
+    padding: 0 8px;
+    min-width: 32px;
+    margin-left: auto;
+  }
+}
+
+.meta-row {
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  flex-wrap: wrap;
+  gap: 8px;
+}
+
+.label-tags {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 4px;
+  flex: 1;
+  max-width: 60%;
+}
+
+.time-ago {
+  margin-left: auto;
+  color: #999;
+  font-size: 12px;
+  white-space: nowrap;
+  
+  i {
+    margin-right: 4px;
+  }
+}
+
+.info-label {
+  display: none;
+}
+
+.monitor-card-status {
+  margin-left: auto;
+  
+  .ant-tag {
+    margin-right: 0;
+  }
+}
+
+.label-item {
+  display: none;
+}
+
+.danger-text {
+  color: #ff4d4f;
+}
+
+@media (max-width: 768px) {
+  .meta-row {
+    flex-direction: column;
+    align-items: flex-start;
+  }
+  
+  .time-ago {
+    margin-left: 0;
+    margin-top: 8px;
+  }
+    
+  .label-tags {
+    max-width: 100%;
+  }
+}
+
+[data-theme='dark'] {
+  :host {
+    .monitor-card {
+      background-color: @common-background-color-dark;
+    } 
+  }
+}
diff --git 
a/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.ts 
b/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.ts
index 70ff6aa4df..a3b509fdb6 100644
--- a/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.ts
+++ b/web-app/src/app/routes/monitor/monitor-list/monitor-list.component.ts
@@ -492,18 +492,8 @@ export class MonitorListComponent implements OnInit, 
OnDestroy {
     this.notifySvc.success(this.i18nSvc.fanyi('common.notify.copy-success'), 
'');
   }
 
-  /**
-   * Paging callback
-   *
-   * @param params page info
-   */
-  onTablePageChange(params: NzTableQueryParams) {
-    const { pageSize, pageIndex, sort, filter } = params;
+  onPageIndexChange(pageIndex: number) {
     this.pageIndex = pageIndex;
-    this.pageSize = pageSize;
-    const currentSort = sort.find(item => item.value !== null);
-    this.currentSortField = (currentSort && currentSort.key) || null;
-    this.currentSortOrder = (currentSort && currentSort.value) || null;
     this.changeMonitorTable(this.currentSortField, this.currentSortOrder);
   }
 
@@ -604,17 +594,7 @@ export class MonitorListComponent implements OnInit, 
OnDestroy {
     return hash;
   }
 
-  copyMonitor() {
-    if (this.checkedMonitorIds == null || this.checkedMonitorIds.size === 0) {
-      
this.notifySvc.warning(this.i18nSvc.fanyi('common.notify.no-select-delete'), 
'');
-      return;
-    }
-    if (this.checkedMonitorIds.size > 1) {
-      
this.notifySvc.warning(this.i18nSvc.fanyi('monitor.copy.notify.one-select'), 
'');
-      return;
-    }
-    const monitorId = Array.from(this.checkedMonitorIds)[0];
-
+  copyMonitor(monitorId: number) {
     this.monitorSvc.copyMonitor(monitorId).subscribe(
       message => {
         if (message.code === 0) {
diff --git a/web-app/src/app/routes/monitor/monitor.module.ts 
b/web-app/src/app/routes/monitor/monitor.module.ts
index 8f0c67e32e..48f53be47f 100644
--- a/web-app/src/app/routes/monitor/monitor.module.ts
+++ b/web-app/src/app/routes/monitor/monitor.module.ts
@@ -26,6 +26,7 @@ import { NzDescriptionsModule } from 
'ng-zorro-antd/descriptions';
 import { NzDividerModule } from 'ng-zorro-antd/divider';
 import { NzLayoutModule } from 'ng-zorro-antd/layout';
 import { NzListModule } from 'ng-zorro-antd/list';
+import { NzPaginationModule } from 'ng-zorro-antd/pagination';
 import { NzRadioModule } from 'ng-zorro-antd/radio';
 import { NzSpaceModule } from 'ng-zorro-antd/space';
 import { NzSwitchModule } from 'ng-zorro-antd/switch';
@@ -70,7 +71,8 @@ const COMPONENTS: Array<Type<void>> = [
     NzUploadModule,
     SafePipe,
     NzListModule,
-    NzDescriptionsModule
+    NzDescriptionsModule,
+    NzPaginationModule
   ],
   declarations: COMPONENTS
 })


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

Reply via email to