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

mfholz pushed a commit to branch add-clone-function-to-data-explorer
in repository https://gitbox.apache.org/repos/asf/streampipes.git

commit f852034cb6934dac18bc0cb9c347b37cf39a8ee7
Author: Marcelfrueh <[email protected]>
AuthorDate: Mon May 5 15:43:13 2025 +0200

    feat: add clone button to data explorer overview
---
 ui/deployment/i18n/de.json                         |  4 ++-
 ui/deployment/i18n/en.json                         |  4 ++-
 .../src/lib/apis/chart.service.ts                  | 32 +++++++++++++++++++++-
 .../data-explorer-overview-table.component.html    |  9 ++++++
 .../data-explorer-overview-table.component.ts      |  6 ++++
 5 files changed, 52 insertions(+), 3 deletions(-)

diff --git a/ui/deployment/i18n/de.json b/ui/deployment/i18n/de.json
index 5352dd885b..5b08c9c1d0 100644
--- a/ui/deployment/i18n/de.json
+++ b/ui/deployment/i18n/de.json
@@ -155,6 +155,7 @@
   "Edit chart": "Diagramm bearbeiten",
   "Manage permissions": "Berechtigungen verwalten",
   "Delete chart": "Diagramm löschen",
+  "Clone chart": "Diagramm kopieren",
   "Chart Name": "Diagrammname",
   "Save": "Speichern",
   "Discard": "Verwerfen",
@@ -410,5 +411,6 @@
   "30 min": "30 Minuten",
   "Error Details": "Fehler-Details",
   "Resources": "Ressourcen",
-  "All {{allResourcesAlias}}": "Alle {{allResourcesAlias}}"
+  "All {{allResourcesAlias}}": "Alle {{allResourcesAlias}}",
+  "{{ widgetTitle }} Clone": "{{ widgetTitle }} Kopie"
 }
diff --git a/ui/deployment/i18n/en.json b/ui/deployment/i18n/en.json
index 9264e48626..fd8a9cc6c0 100644
--- a/ui/deployment/i18n/en.json
+++ b/ui/deployment/i18n/en.json
@@ -155,6 +155,7 @@
   "Edit chart": null,
   "Manage permissions": null,
   "Delete chart": null,
+  "Clone chart": null,
   "Chart Name": null,
   "Save": null,
   "Discard": null,
@@ -410,5 +411,6 @@
   "30 min": null,
   "Error Details": null,
   "Resources": null,
-  "All {{allResourcesAlias}}": "All {{allResourcesAlias}}"
+  "All {{allResourcesAlias}}": "All {{allResourcesAlias}}",
+  "{{ widgetTitle }} Clone": "{{ widgetTitle }} Clone"
 }
diff --git 
a/ui/projects/streampipes/platform-services/src/lib/apis/chart.service.ts 
b/ui/projects/streampipes/platform-services/src/lib/apis/chart.service.ts
index 357b2fe655..f14946c697 100644
--- a/ui/projects/streampipes/platform-services/src/lib/apis/chart.service.ts
+++ b/ui/projects/streampipes/platform-services/src/lib/apis/chart.service.ts
@@ -24,12 +24,16 @@ import {
     DataExplorerWidgetModel,
     DataLakeMeasure,
 } from '../model/gen/streampipes-model';
+import { TranslateService } from '@ngx-translate/core';
 
 @Injectable({
     providedIn: 'root',
 })
 export class ChartService {
-    constructor(private http: HttpClient) {}
+    constructor(
+        private http: HttpClient,
+        private translateService: TranslateService,
+    ) {}
 
     getAllCharts(): Observable<DataExplorerWidgetModel[]> {
         return this.http
@@ -66,6 +70,32 @@ export class ChartService {
         return this.http.delete(`${this.dashboardWidgetUrl}/${widgetId}`);
     }
 
+    cloneChart(
+        widget: DataExplorerWidgetModel,
+    ): Observable<DataExplorerWidgetModel> {
+        const clone = JSON.parse(JSON.stringify(widget));
+        clone.elementId = undefined;
+        clone.rev = undefined;
+
+        clone.baseAppearanceConfig.widgetTitle = this.translateService.instant(
+            '{{ widgetTitle }} Clone',
+            { widgetTitle: widget.baseAppearanceConfig.widgetTitle },
+        );
+
+        clone.metadata = {
+            createdAtEpochMs: Date.now(),
+            lastModifiedEpochMs: Date.now(),
+        };
+
+        return this.http.post(this.dashboardWidgetUrl, clone).pipe(
+            map(response => {
+                return DataExplorerWidgetModel.fromData(
+                    response as DataExplorerWidgetModel,
+                );
+            }),
+        );
+    }
+
     updateChart(widget: DataExplorerWidgetModel): Observable<any> {
         return this.http.put(
             this.dashboardWidgetUrl + '/' + widget.elementId,
diff --git 
a/ui/src/app/data-explorer/components/overview/data-explorer-overview-table/data-explorer-overview-table.component.html
 
b/ui/src/app/data-explorer/components/overview/data-explorer-overview-table/data-explorer-overview-table.component.html
index 0f6581437f..65a615065c 100644
--- 
a/ui/src/app/data-explorer/components/overview/data-explorer-overview-table/data-explorer-overview-table.component.html
+++ 
b/ui/src/app/data-explorer/components/overview/data-explorer-overview-table/data-explorer-overview-table.component.html
@@ -143,6 +143,15 @@
                         >
                             <i class="material-icons">share</i>
                         </button>
+                        <button
+                            mat-icon-button
+                            color="accent"
+                            [matTooltip]="'Clone chart' | translate"
+                            *ngIf="hasDataExplorerWritePrivileges"
+                            (click)="cloneDataView(element)"
+                        >
+                            <i class="material-icons">flip_to_front</i>
+                        </button>
                         <button
                             mat-icon-button
                             color="accent"
diff --git 
a/ui/src/app/data-explorer/components/overview/data-explorer-overview-table/data-explorer-overview-table.component.ts
 
b/ui/src/app/data-explorer/components/overview/data-explorer-overview-table/data-explorer-overview-table.component.ts
index c8b9d12733..4080dd632e 100644
--- 
a/ui/src/app/data-explorer/components/overview/data-explorer-overview-table/data-explorer-overview-table.component.ts
+++ 
b/ui/src/app/data-explorer/components/overview/data-explorer-overview-table/data-explorer-overview-table.component.ts
@@ -131,6 +131,12 @@ export class SpDataExplorerDataViewOverviewComponent 
extends SpDataExplorerOverv
         });
     }
 
+    cloneDataView(dataView: DataExplorerWidgetModel) {
+        this.dataViewService.cloneChart(dataView).subscribe(() => {
+            this.getDataViews();
+        });
+    }
+
     applyChartFilters(elementIds: Set<string> = new Set<string>()): void {
         if (elementIds.size == 0) {
             this.filteredCharts = this.charts;

Reply via email to