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

riemer pushed a commit to branch 
3182-deleted-data-view-still-appears-in-dashboard
in repository https://gitbox.apache.org/repos/asf/streampipes.git


The following commit(s) were added to 
refs/heads/3182-deleted-data-view-still-appears-in-dashboard by this push:
     new 61ac16e76f fix(#3182): Remove data views from dashboards after deletion
61ac16e76f is described below

commit 61ac16e76f7b9778f3ca03ebe22563ec9740201c
Author: Dominik Riemer <[email protected]>
AuthorDate: Tue Aug 27 23:35:36 2024 +0200

    fix(#3182): Remove data views from dashboards after deletion
---
 .../DataExplorerWidgetResourceManager.java         | 18 +++++++++++++++-
 .../resource/management/SpResourceManager.java     |  5 +++--
 .../rest/impl/datalake/DataLakeWidgetResource.java | 10 ++++++++-
 .../lib/apis/data-view-data-explorer.service.ts    |  7 ++++--
 .../data-explorer-data-view.component.html         |  6 +++++-
 .../data-view/data-explorer-data-view.component.ts |  1 -
 .../data-explorer-dashboard-overview.component.ts  |  2 +-
 .../data-explorer-data-view-overview.component.ts  |  3 ++-
 .../widget-view/abstract-widget-view.directive.ts  | 25 +++++++++++++---------
 9 files changed, 57 insertions(+), 20 deletions(-)

diff --git 
a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataExplorerWidgetResourceManager.java
 
b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataExplorerWidgetResourceManager.java
index 9176b3bf43..9ec75d026e 100644
--- 
a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataExplorerWidgetResourceManager.java
+++ 
b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/DataExplorerWidgetResourceManager.java
@@ -23,7 +23,23 @@ import org.apache.streampipes.storage.api.CRUDStorage;
 
 public class DataExplorerWidgetResourceManager extends 
AbstractCRUDResourceManager<DataExplorerWidgetModel> {
 
-  public 
DataExplorerWidgetResourceManager(CRUDStorage<DataExplorerWidgetModel> db) {
+  private final DataExplorerResourceManager dashboardManager;
+
+  public DataExplorerWidgetResourceManager(DataExplorerResourceManager 
dashboardManager,
+                                           
CRUDStorage<DataExplorerWidgetModel> db) {
     super(db, DataExplorerWidgetModel.class);
+    this.dashboardManager = dashboardManager;
+  }
+
+  @Override
+  public void delete(String elementId) {
+    deleteDataViewsFromDashboard(elementId);
+    super.delete(elementId);
+  }
+
+  private void deleteDataViewsFromDashboard(String widgetElementId) {
+    dashboardManager.findAll().stream()
+        .filter(dashboard -> dashboard.getWidgets().removeIf(w -> 
w.getId().equals(widgetElementId)))
+        .forEach(dashboardManager::update);
   }
 }
diff --git 
a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/SpResourceManager.java
 
b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/SpResourceManager.java
index 5f202f4b81..9e080dfa65 100644
--- 
a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/SpResourceManager.java
+++ 
b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/SpResourceManager.java
@@ -38,8 +38,9 @@ public class SpResourceManager {
     return new DataExplorerResourceManager();
   }
 
-  public DataExplorerWidgetResourceManager 
manageDataExplorerWidget(CRUDStorage<DataExplorerWidgetModel> db) {
-    return new DataExplorerWidgetResourceManager(db);
+  public DataExplorerWidgetResourceManager 
manageDataExplorerWidget(DataExplorerResourceManager dashboardManager,
+                                                                    
CRUDStorage<DataExplorerWidgetModel> db) {
+    return new DataExplorerWidgetResourceManager(dashboardManager, db);
   }
 
   public DataProcessorResourceManager manageDataProcessors() {
diff --git 
a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeWidgetResource.java
 
b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeWidgetResource.java
index e8743a93a7..099a7502de 100644
--- 
a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeWidgetResource.java
+++ 
b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/datalake/DataLakeWidgetResource.java
@@ -20,10 +20,12 @@ package org.apache.streampipes.rest.impl.datalake;
 
 import org.apache.streampipes.model.client.user.Privilege;
 import org.apache.streampipes.model.datalake.DataExplorerWidgetModel;
+import org.apache.streampipes.resource.management.DataExplorerResourceManager;
 import 
org.apache.streampipes.resource.management.DataExplorerWidgetResourceManager;
 import org.apache.streampipes.resource.management.SpResourceManager;
 import 
org.apache.streampipes.rest.core.base.impl.AbstractAuthGuardedRestResource;
 import org.apache.streampipes.rest.security.AuthConstants;
+import org.apache.streampipes.rest.shared.exception.BadRequestException;
 
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
@@ -48,6 +50,7 @@ public class DataLakeWidgetResource extends 
AbstractAuthGuardedRestResource {
 
   public DataLakeWidgetResource() {
     this.resourceManager = new SpResourceManager().manageDataExplorerWidget(
+        new DataExplorerResourceManager(),
         getNoSqlStorage().getDataExplorerWidgetStorage()
     );
   }
@@ -62,7 +65,12 @@ public class DataLakeWidgetResource extends 
AbstractAuthGuardedRestResource {
   @GetMapping(path = "/{widgetId}", produces = 
MediaType.APPLICATION_JSON_VALUE)
   @PreAuthorize("this.hasReadAuthority() and hasPermission(#elementId, 
'READ')")
   public ResponseEntity<DataExplorerWidgetModel> 
getDataExplorerWidget(@PathVariable("widgetId") String elementId) {
-    return ok(resourceManager.find(elementId));
+    var widget = resourceManager.find(elementId);
+    if (widget != null) {
+      return ok(widget);
+    } else {
+      throw new BadRequestException("Could not find widget");
+    }
   }
 
   @PutMapping(
diff --git 
a/ui/projects/streampipes/platform-services/src/lib/apis/data-view-data-explorer.service.ts
 
b/ui/projects/streampipes/platform-services/src/lib/apis/data-view-data-explorer.service.ts
index 320432ad4a..51e71213c6 100644
--- 
a/ui/projects/streampipes/platform-services/src/lib/apis/data-view-data-explorer.service.ts
+++ 
b/ui/projects/streampipes/platform-services/src/lib/apis/data-view-data-explorer.service.ts
@@ -16,8 +16,8 @@
  *
  */
 
-import { HttpClient } from '@angular/common/http';
-import { Observable } from 'rxjs';
+import { HttpClient, HttpErrorResponse } from '@angular/common/http';
+import { catchError, Observable, throwError } from 'rxjs';
 import { map } from 'rxjs/operators';
 import { Dashboard } from '../model/dashboard/dashboard.model';
 import { Injectable } from '@angular/core';
@@ -91,6 +91,9 @@ export class DataViewDataExplorerService {
 
     getWidget(widgetId: string): Observable<DataExplorerWidgetModel> {
         return this.http.get(this.dashboardWidgetUrl + '/' + widgetId).pipe(
+            catchError(() => {
+                return throwError(() => new Error('Failed to get widget 
data'));
+            }),
             map(response => {
                 return DataExplorerWidgetModel.fromData(
                     response as DataExplorerWidgetModel,
diff --git 
a/ui/src/app/data-explorer/components/data-view/data-explorer-data-view.component.html
 
b/ui/src/app/data-explorer/components/data-view/data-explorer-data-view.component.html
index 52212aeeba..2c8ec433c8 100644
--- 
a/ui/src/app/data-explorer/components/data-view/data-explorer-data-view.component.html
+++ 
b/ui/src/app/data-explorer/components/data-view/data-explorer-data-view.component.html
@@ -61,7 +61,11 @@
             <mat-drawer-content class="h-100 dashboard-grid">
                 <div #panel fxFlex="100" fxLayout="column">
                     <sp-data-explorer-dashboard-widget
-                        *ngIf="dataView && gridsterItemComponent"
+                        *ngIf="
+                            dataView &&
+                            gridsterItemComponent &&
+                            dataView.dataConfig?.sourceConfigs?.length > 0
+                        "
                         [dataViewMode]="true"
                         [configuredWidget]="dataView"
                         [gridsterItemComponent]="gridsterItemComponent"
diff --git 
a/ui/src/app/data-explorer/components/data-view/data-explorer-data-view.component.ts
 
b/ui/src/app/data-explorer/components/data-view/data-explorer-data-view.component.ts
index a2880731e1..48af90f114 100644
--- 
a/ui/src/app/data-explorer/components/data-view/data-explorer-data-view.component.ts
+++ 
b/ui/src/app/data-explorer/components/data-view/data-explorer-data-view.component.ts
@@ -101,7 +101,6 @@ export class DataExplorerDataViewComponent implements 
OnInit {
     }
 
     createWidget() {
-        this.dataLakeMeasure = new DataLakeMeasure();
         this.dataView = new DataExplorerWidgetModel();
         this.dataView['@class'] =
             'org.apache.streampipes.model.datalake.DataExplorerWidgetModel';
diff --git 
a/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview/data-explorer-dashboard-overview.component.ts
 
b/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview/data-explorer-dashboard-overview.component.ts
index 11dbce196c..c5bb841559 100644
--- 
a/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview/data-explorer-dashboard-overview.component.ts
+++ 
b/ui/src/app/data-explorer/components/overview/data-explorer-dashboard-overview/data-explorer-dashboard-overview.component.ts
@@ -93,7 +93,7 @@ export class SpDataExplorerDashboardOverviewComponent extends 
SpDataExplorerOver
             width: '600px',
             data: {
                 title: 'Are you sure you want to delete this dashboard?',
-                subtitle: 'This action cannot be reversed!',
+                subtitle: 'This action cannot be undone!',
                 cancelTitle: 'Cancel',
                 okTitle: 'Delete Dashboard',
                 confirmAndCancel: true,
diff --git 
a/ui/src/app/data-explorer/components/overview/data-explorer-data-view-overview/data-explorer-data-view-overview.component.ts
 
b/ui/src/app/data-explorer/components/overview/data-explorer-data-view-overview/data-explorer-data-view-overview.component.ts
index 41908f3519..8c2f128fb3 100644
--- 
a/ui/src/app/data-explorer/components/overview/data-explorer-data-view-overview/data-explorer-data-view-overview.component.ts
+++ 
b/ui/src/app/data-explorer/components/overview/data-explorer-data-view-overview/data-explorer-data-view-overview.component.ts
@@ -95,7 +95,8 @@ export class SpDataExplorerDataViewOverviewComponent extends 
SpDataExplorerOverv
             width: '600px',
             data: {
                 title: 'Are you sure you want to delete this data view?',
-                subtitle: 'This action cannot be reversed!',
+                subtitle:
+                    'The data view will be removed from all dashboards as 
well. This action cannot be undone!',
                 cancelTitle: 'Cancel',
                 okTitle: 'Delete Data View',
                 confirmAndCancel: true,
diff --git 
a/ui/src/app/data-explorer/components/widget-view/abstract-widget-view.directive.ts
 
b/ui/src/app/data-explorer/components/widget-view/abstract-widget-view.directive.ts
index 013b4ae9b9..e5c41221d7 100644
--- 
a/ui/src/app/data-explorer/components/widget-view/abstract-widget-view.directive.ts
+++ 
b/ui/src/app/data-explorer/components/widget-view/abstract-widget-view.directive.ts
@@ -25,8 +25,9 @@ import {
     TimeSettings,
 } from '@streampipes/platform-services';
 import { ResizeService } from '../../services/resize.service';
-import { zip } from 'rxjs';
+import { of, zip } from 'rxjs';
 import { DataExplorerWidgetRegistry } from 
'../../registry/data-explorer-widget-registry';
+import { catchError } from 'rxjs/operators';
 
 @Directive()
 export abstract class AbstractWidgetViewDirective {
@@ -82,7 +83,9 @@ export abstract class AbstractWidgetViewDirective {
 
     loadWidgetConfigs() {
         const observables = this.dashboard.widgets.map(w =>
-            this.dataViewDataExplorerService.getWidget(w.id),
+            this.dataViewDataExplorerService
+                .getWidget(w.id)
+                .pipe(catchError(() => of(undefined))),
         );
         zip(...observables).subscribe(results => {
             results.forEach(r => {
@@ -117,14 +120,16 @@ export abstract class AbstractWidgetViewDirective {
     }
 
     processWidget(widget: DataExplorerWidgetModel) {
-        widget.widgetType = this.widgetRegistryService.getWidgetType(
-            widget.widgetType,
-        );
-        this.configuredWidgets.set(widget.elementId, widget);
-        this.dataLakeMeasures.set(
-            widget.elementId,
-            widget.dataConfig.sourceConfigs[0].measure,
-        );
+        if (widget !== undefined) {
+            widget.widgetType = this.widgetRegistryService.getWidgetType(
+                widget.widgetType,
+            );
+            this.configuredWidgets.set(widget.elementId, widget);
+            this.dataLakeMeasures.set(
+                widget.elementId,
+                widget.dataConfig.sourceConfigs[0].measure,
+            );
+        }
     }
 
     propagateItemRemoval(widgetIndex: number) {

Reply via email to