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

dominikriemer pushed a commit to branch add-resource-dtos
in repository https://gitbox.apache.org/repos/asf/streampipes.git

commit 526dde69feeb96dfaeaf7f09c38daad0320a9420
Author: Dominik Riemer <[email protected]>
AuthorDate: Fri Jun 12 21:55:16 2026 +0200

    Improve dashbord table
---
 .../model/dashboard/DashboardSummaryDto.java       |   4 +-
 .../management/DataExplorerResourceManager.java    |  34 ++++-
 .../lib/model/resource/resource-summary.model.ts   |   4 +-
 .../dashboard-overview-table.component.html        |   4 +-
 .../dashboard-overview-table.component.ts          | 140 +++++++++++----------
 5 files changed, 110 insertions(+), 76 deletions(-)

diff --git 
a/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardSummaryDto.java
 
b/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardSummaryDto.java
index cd1c04fcd7..fad916fce9 100644
--- 
a/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardSummaryDto.java
+++ 
b/streampipes-model/src/main/java/org/apache/streampipes/model/dashboard/DashboardSummaryDto.java
@@ -21,6 +21,6 @@ package org.apache.streampipes.model.dashboard;
 public record DashboardSummaryDto(String elementId,
                                   String name,
                                   String description,
-                                  long createdAtEpochMs,
-                                  long lastModifiedEpochMs) {
+                                  Long createdAtEpochMs,
+                                  Long lastModifiedEpochMs) {
 }
diff --git 
a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataExplorerResourceManager.java
 
b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataExplorerResourceManager.java
index f4fd8d00c0..2a5d2fc65d 100644
--- 
a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataExplorerResourceManager.java
+++ 
b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataExplorerResourceManager.java
@@ -48,10 +48,10 @@ public class DataExplorerResourceManager extends 
CrudResourceManager<DashboardMo
         .filter(dashboard -> permissionEvaluator.hasPermission(auth, 
dashboard.getElementId(), "READ"))
         .map(dashboard -> new DashboardSummaryDto(
             dashboard.getElementId(),
-            dashboard.getName(),
-            dashboard.getDescription(),
-            dashboard.getMetadata().getCreatedAtEpochMs(),
-            dashboard.getMetadata().getLastModifiedEpochMs()))
+            getDashboardName(dashboard),
+            getDashboardDescription(dashboard),
+            getCreatedAt(dashboard),
+            getLastModified(dashboard)))
         .toList();
 
     return new ResourceSummaryDto<>(dashboards, dashboards.size());
@@ -76,4 +76,30 @@ public class DataExplorerResourceManager extends 
CrudResourceManager<DashboardMo
         .map(String.class::cast)
         .toList();
   }
+
+  private String getDashboardName(DashboardModel dashboard) {
+    if (dashboard == null) {
+      return null;
+    }
+
+    return dashboard.getName() != null ? dashboard.getName() : 
dashboard.getElementId();
+  }
+
+  private String getDashboardDescription(DashboardModel dashboard) {
+    return dashboard != null && dashboard.getDescription() != null
+        ? dashboard.getDescription()
+        : "";
+  }
+
+  private Long getCreatedAt(DashboardModel dashboard) {
+    return dashboard != null && dashboard.getMetadata() != null
+        ? dashboard.getMetadata().getCreatedAtEpochMs()
+        : null;
+  }
+
+  private Long getLastModified(DashboardModel dashboard) {
+    return dashboard != null && dashboard.getMetadata() != null
+        ? dashboard.getMetadata().getLastModifiedEpochMs()
+        : null;
+  }
 }
diff --git 
a/ui/projects/streampipes/platform-services/src/lib/model/resource/resource-summary.model.ts
 
b/ui/projects/streampipes/platform-services/src/lib/model/resource/resource-summary.model.ts
index 28b9aa3457..9e714179a4 100644
--- 
a/ui/projects/streampipes/platform-services/src/lib/model/resource/resource-summary.model.ts
+++ 
b/ui/projects/streampipes/platform-services/src/lib/model/resource/resource-summary.model.ts
@@ -28,8 +28,8 @@ export interface DashboardSummaryDto {
     elementId: string;
     name: string;
     description: string;
-    createdAtEpochMs: number;
-    lastModifiedEpochMs: number;
+    createdAtEpochMs: number | null;
+    lastModifiedEpochMs: number | null;
 }
 
 export interface PipelineSummaryDto {
diff --git 
a/ui/src/app/dashboard/components/overview/dashboard-overview-table/dashboard-overview-table.component.html
 
b/ui/src/app/dashboard/components/overview/dashboard-overview-table/dashboard-overview-table.component.html
index fec74756b8..561f4657c3 100644
--- 
a/ui/src/app/dashboard/components/overview/dashboard-overview-table/dashboard-overview-table.component.html
+++ 
b/ui/src/app/dashboard/components/overview/dashboard-overview-table/dashboard-overview-table.component.html
@@ -61,7 +61,7 @@
                 <td mat-cell *matCellDef="let element">
                     @if (element.lastModifiedEpochMs !== null) {
                         <div>
-                            {{ this.formatDate(element.lastModifiedEpochMs) }}
+                            {{ formatDate(element.lastModifiedEpochMs) }}
                         </div>
                     } @else {
                         <div>–</div>
@@ -76,7 +76,7 @@
                 <td mat-cell *matCellDef="let element">
                     @if (element.createdAtEpochMs !== null) {
                         <div>
-                            {{ this.formatDate(element.createdAtEpochMs) }}
+                            {{ formatDate(element.createdAtEpochMs) }}
                         </div>
                     } @else {
                         <div>–</div>
diff --git 
a/ui/src/app/dashboard/components/overview/dashboard-overview-table/dashboard-overview-table.component.ts
 
b/ui/src/app/dashboard/components/overview/dashboard-overview-table/dashboard-overview-table.component.ts
index d31c558a07..e1061d8447 100644
--- 
a/ui/src/app/dashboard/components/overview/dashboard-overview-table/dashboard-overview-table.component.ts
+++ 
b/ui/src/app/dashboard/components/overview/dashboard-overview-table/dashboard-overview-table.component.ts
@@ -138,7 +138,9 @@ export class DashboardOverviewTableComponent implements 
OnInit, OnDestroy {
             });
 
         this.dataSource.sortingDataAccessor = (dashboard, column) => {
-            if (column === 'lastModified') {
+            if (column === 'name') {
+                return dashboard.name;
+            } else if (column === 'lastModified') {
                 return dashboard.lastModifiedEpochMs;
             } else if (column === 'createdAt') {
                 return dashboard.createdAtEpochMs;
@@ -149,49 +151,46 @@ export class DashboardOverviewTableComponent implements 
OnInit, OnDestroy {
         this.getDashboards();
     }
 
-    showManageDialog(dashboard: DashboardSummaryDto) {
-        this.dashboardService
-            .getDashboard(dashboard.elementId)
-            .subscribe(resource => {
-                const resourceConfig: 
ObjectManageDialogResourceConfig<Dashboard> =
-                    {
-                        resourceLabel: 'Dashboard',
-                        nameLabel: 'Name',
-                        descriptionLabel: 'Description',
-                        nameProperty: 'name',
-                        assetLinkType: 'dashboard',
-                        assetLinkCheckboxLabel:
-                            'Add the current dashboard to an existing asset',
-                        saveResource: resource =>
-                            this.dashboardService.updateDashboard(resource),
-                    };
-                const dialogRef = this.dialogService.open(
-                    ObjectManageDialogComponent,
-                    {
-                        panelType: PanelType.SLIDE_IN_PANEL,
-                        title: this.translateService.instant('Manage'),
-                        width: '50vw',
-                        data: {
-                            objectInstanceId: resource.elementId,
-                            resource: { ...resource },
-                            saveMode: 'immediate',
-                            resourceConfig,
-                            headerTitle:
-                                this.translateService.instant(
-                                    'Manage Dashboard ',
-                                ) + resource.name,
-                        },
+    showManageDialog(dashboard: DashboardSummaryDto): void {
+        this.withDashboard(dashboard, resource => {
+            const resourceConfig: ObjectManageDialogResourceConfig<Dashboard> =
+                {
+                    resourceLabel: 'Dashboard',
+                    nameLabel: 'Name',
+                    descriptionLabel: 'Description',
+                    nameProperty: 'name',
+                    assetLinkType: 'dashboard',
+                    assetLinkCheckboxLabel:
+                        'Add the current dashboard to an existing asset',
+                    saveResource: resource =>
+                        this.dashboardService.updateDashboard(resource),
+                };
+            const dialogRef = this.dialogService.open(
+                ObjectManageDialogComponent,
+                {
+                    panelType: PanelType.SLIDE_IN_PANEL,
+                    title: this.translateService.instant('Manage'),
+                    width: '50vw',
+                    data: {
+                        objectInstanceId: resource.elementId,
+                        resource: { ...resource },
+                        saveMode: 'immediate',
+                        resourceConfig,
+                        headerTitle:
+                            this.translateService.instant('Manage Dashboard ') 
+
+                            resource.name,
                     },
-                );
-                dialogRef.afterClosed().subscribe(refresh => {
-                    if (refresh) {
-                        this.getDashboards();
-                    }
-                });
+                },
+            );
+            dialogRef.afterClosed().subscribe(refresh => {
+                if (refresh) {
+                    this.getDashboards();
+                }
             });
+        });
     }
 
-    openDeleteDashboardDialog(dashboard: DashboardSummaryDto) {
+    openDeleteDashboardDialog(dashboard: DashboardSummaryDto): void {
         const dialogRef = this.dialog.open(ConfirmDialogComponent, {
             width: '600px',
             data: {
@@ -219,15 +218,15 @@ export class DashboardOverviewTableComponent implements 
OnInit, OnDestroy {
         });
     }
 
-    showDashboard(dashboard: DashboardSummaryDto) {
+    showDashboard(dashboard: DashboardSummaryDto): void {
         this.routingService.navigateToDashboard(false, dashboard.elementId);
     }
 
-    editDashboard(dashboard: DashboardSummaryDto) {
+    editDashboard(dashboard: DashboardSummaryDto): void {
         this.routingService.navigateToDashboard(true, dashboard.elementId);
     }
 
-    getDashboards() {
+    getDashboards(): void {
         this.dashboardService.getDashboardSummary().subscribe(data => {
             this.dashboards = data.resources.sort((a, b) =>
                 a.name.localeCompare(b.name),
@@ -237,9 +236,9 @@ export class DashboardOverviewTableComponent implements 
OnInit, OnDestroy {
     }
 
     applyDashboardFilters(elementIds: Set<string>): void {
-        if (elementIds == undefined) {
+        if (elementIds === undefined) {
             this.filteredDashboards = [];
-        } else if (elementIds.size == 0) {
+        } else if (elementIds.size === 0) {
             this.filteredDashboards = this.dashboards;
         } else {
             this.filteredDashboards = this.dashboards.filter(a =>
@@ -254,7 +253,7 @@ export class DashboardOverviewTableComponent implements 
OnInit, OnDestroy {
         return this.dateFormatService.formatDate(timestamp);
     }
 
-    openDashboardInKioskMode(dashboard: Dashboard) {
+    openDashboardInKioskMode(dashboard: DashboardSummaryDto): void {
         this.router.navigate(['dashboard-kiosk', dashboard.elementId]);
     }
 
@@ -263,33 +262,42 @@ export class DashboardOverviewTableComponent implements 
OnInit, OnDestroy {
     }
 
     openCloneDialog(dashboardSummary: DashboardSummaryDto): void {
-        this.dashboardService
-            .getDashboard(dashboardSummary.elementId)
-            .subscribe(dashboard => {
-                const dialogRef = this.dialogService.open(
-                    CloneDashboardDialogComponent,
-                    {
-                        panelType: PanelType.SLIDE_IN_PANEL,
-                        title: this.translateService.instant('Clone 
dashboard'),
-                        width: '50vw',
-                        data: {
-                            dashboard: dashboard,
-                        },
+        this.withDashboard(dashboardSummary, dashboard => {
+            const dialogRef = this.dialogService.open(
+                CloneDashboardDialogComponent,
+                {
+                    panelType: PanelType.SLIDE_IN_PANEL,
+                    title: this.translateService.instant('Clone dashboard'),
+                    width: '50vw',
+                    data: {
+                        dashboard: dashboard,
                     },
-                );
-                dialogRef.afterClosed().subscribe(result => {
-                    if (result) {
-                        this.getDashboards();
-                    }
-                });
+                },
+            );
+            dialogRef.afterClosed().subscribe(result => {
+                if (result) {
+                    this.getDashboards();
+                }
             });
+        });
     }
 
-    onRowClicked(dashboard: DashboardSummaryDto) {
+    onRowClicked(dashboard: DashboardSummaryDto): void {
         this.showDashboard(dashboard);
     }
 
-    ngOnDestroy() {
+    ngOnDestroy(): void {
         this.assetFilter$?.unsubscribe();
     }
+
+    private withDashboard(
+        dashboardSummary: DashboardSummaryDto,
+        callback: (dashboard: Dashboard) => void,
+    ): void {
+        this.dashboardService
+            .getDashboard(dashboardSummary.elementId)
+            .subscribe(dashboard => {
+                callback(dashboard);
+            });
+    }
 }

Reply via email to