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) {