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

riemer pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/streampipes.git


The following commit(s) were added to refs/heads/dev by this push:
     new 89bfeb29d8 feat: add panel resize component (#3585)
89bfeb29d8 is described below

commit 89bfeb29d8a87939b422a214217752d7e802d5af
Author: Marcel Früholz <[email protected]>
AuthorDate: Fri May 23 12:55:02 2025 +0200

    feat: add panel resize component (#3585)
    
    * feat: add panel resize component
    
    * Resize panel on dragEnd only
    
    * Fix resizing of content panel
    
    * Improve resizing of charts
    
    ---------
    
    Co-authored-by: Dominik Riemer <[email protected]>
---
 .../sidebar-resize/sidebar-resize.component.html   | 36 +++++++++++
 .../sidebar-resize/sidebar-resize.component.scss}  | 64 ++++++++++----------
 .../sidebar-resize/sidebar-resize.component.ts     | 70 ++++++++++++++++++++++
 .../shared-ui/src/lib/shared-ui.module.ts          |  5 ++
 .../streampipes/shared-ui/src/public-api.ts        |  1 +
 .../charts/base/echarts-widget.component.ts        | 19 ++++--
 .../services/resize-echarts.service.ts}            | 46 +++-----------
 .../data-explorer-chart-view.component.html        | 23 ++++---
 .../data-explorer-chart-view.component.scss        |  5 +-
 .../data-explorer-chart-view.component.ts          | 23 ++++++-
 10 files changed, 209 insertions(+), 83 deletions(-)

diff --git 
a/ui/projects/streampipes/shared-ui/src/lib/components/sidebar-resize/sidebar-resize.component.html
 
b/ui/projects/streampipes/shared-ui/src/lib/components/sidebar-resize/sidebar-resize.component.html
new file mode 100644
index 0000000000..56f62f8e08
--- /dev/null
+++ 
b/ui/projects/streampipes/shared-ui/src/lib/components/sidebar-resize/sidebar-resize.component.html
@@ -0,0 +1,36 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~    http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+<div class="outer-container">
+    <div
+        *ngIf="isDragging"
+        class="ghost-bar"
+        [style.right.px]="ghostLeft"
+    ></div>
+    <div class="resize-container" [style.width.px]="currentWidth">
+        <div
+            class="resizer"
+            cdkDrag
+            (cdkDragStarted)="onDragStarted($event)"
+            (cdkDragMoved)="onDragMoved($event)"
+            (cdkDragEnded)="onDragEnded()"
+        >
+            <span class="drag-icon">⠿</span>
+        </div>
+        <ng-content></ng-content>
+    </div>
+</div>
diff --git 
a/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.scss
 
b/ui/projects/streampipes/shared-ui/src/lib/components/sidebar-resize/sidebar-resize.component.scss
similarity index 58%
copy from 
ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.scss
copy to 
ui/projects/streampipes/shared-ui/src/lib/components/sidebar-resize/sidebar-resize.component.scss
index b8ebed30f9..c70032259e 100644
--- 
a/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.scss
+++ 
b/ui/projects/streampipes/shared-ui/src/lib/components/sidebar-resize/sidebar-resize.component.scss
@@ -1,4 +1,4 @@
-/*
+/*!
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -16,44 +16,46 @@
  *
  */
 
-.fixed-height {
-    height: 50px;
-}
-
-.data-explorer-options {
-    padding: 0px;
-}
-
-.data-explorer-options-item {
-    display: inline;
-    margin-right: 10px;
-}
-
-.m-20 {
-    margin: 20px;
+.resizer {
+    width: 6px;
+    cursor: ew-resize;
+    background: rgba(0, 0, 0, 0.1);
+    height: 100%;
+    position: absolute;
+    z-index: 10;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    &:hover {
+        background-color: #aaa;
+    }
 }
 
-.h-100 {
-    height: 100%;
+.drag-icon {
+    font-size: 10px;
+    color: #555;
 }
 
-.dashboard-grid {
-    display: flex;
-    flex-direction: column;
-    flex: 1 1 100%;
+.ghost-bar {
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    width: 2px;
+    background-color: var(--color-bg-3);
+    z-index: 100;
+    pointer-events: none;
 }
 
-.designer-panel-container {
+.outer-container {
+    position: relative;
     width: 100%;
     height: 100%;
 }
 
-.designer-panel {
-    width: 450px;
-    border: 1px solid var(--color-tab-border);
-}
-
-.widget-title-text {
-    white-space: nowrap;
-    margin-right: 12px;
+.resize-container {
+    position: relative;
+    height: 100%;
+    display: flex;
+    flex-direction: row;
+    overflow: hidden;
 }
diff --git 
a/ui/projects/streampipes/shared-ui/src/lib/components/sidebar-resize/sidebar-resize.component.ts
 
b/ui/projects/streampipes/shared-ui/src/lib/components/sidebar-resize/sidebar-resize.component.ts
new file mode 100644
index 0000000000..39e57e020c
--- /dev/null
+++ 
b/ui/projects/streampipes/shared-ui/src/lib/components/sidebar-resize/sidebar-resize.component.ts
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Component, EventEmitter, inject, Input, Output } from '@angular/core';
+import { CdkDragMove, CdkDragStart } from '@angular/cdk/drag-drop';
+import { MatDrawerContainer } from '@angular/material/sidenav';
+
+@Component({
+    selector: 'sp-sidebar-resize',
+    templateUrl: './sidebar-resize.component.html',
+    styleUrls: ['./sidebar-resize.component.scss'],
+})
+export class SidebarResizeComponent {
+    @Input() currentWidth: number = 450;
+    @Input() minWidth: number = 450;
+    @Input() maxWidth: number = 1000;
+
+    @Output() widthChanged = new EventEmitter<number>();
+
+    private drawerContainer = inject(MatDrawerContainer);
+
+    isDragging = false;
+    ghostLeft = 0;
+    startX = 0;
+    startWidth = 0;
+
+    protected onDragStarted(event: CdkDragStart) {
+        this.isDragging = true;
+
+        const element = event.source.element.nativeElement.parentElement;
+        const rect = element.getBoundingClientRect();
+
+        this.startX = rect.left;
+        this.startWidth = this.currentWidth;
+
+        this.ghostLeft = this.startWidth;
+    }
+
+    protected onDragMoved(event: CdkDragMove) {
+        const deltaX = -event.distance.x;
+        this.ghostLeft = Math.min(
+            Math.max(this.startWidth + deltaX, this.minWidth),
+            this.maxWidth,
+        );
+        const element = event.source.element.nativeElement;
+        element.style.transform = 'none';
+    }
+
+    protected onDragEnded() {
+        this.isDragging = false;
+        this.currentWidth = this.ghostLeft;
+        this.widthChanged.emit(this.currentWidth);
+        setTimeout(() => this.drawerContainer.updateContentMargins(), 0);
+    }
+}
diff --git a/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts 
b/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts
index 394a8caa6c..0ead4013e3 100644
--- a/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts
+++ b/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts
@@ -65,6 +65,7 @@ import { TimeRangeSelectorComponent } from 
'./components/time-selector/time-rang
 import { TimeRangeSelectorMenuComponent } from 
'./components/time-selector/time-selector-menu/time-selector-menu.component';
 import { CustomTimeRangeSelectionComponent } from 
'./components/time-selector/time-selector-menu/custom-time-range-selection/custom-time-range-selection.component';
 import { DataExplorerRefreshIntervalSettingsComponent } from 
'./components/time-selector/refresh-interval-settings/refresh-interval-settings.component';
+import { SidebarResizeComponent } from 
'./components/sidebar-resize/sidebar-resize.component';
 import { MatSelectModule } from '@angular/material/select';
 import { MatFormFieldModule } from '@angular/material/form-field';
 import { MatMenuModule } from '@angular/material/menu';
@@ -96,6 +97,7 @@ import { InputSchemaPanelComponent } from 
'./components/input-schema-panel/input
 import { InputSchemaPropertyComponent } from 
'./components/input-schema-panel/input-schema-property/input-schema-property.component';
 import { MatExpansionModule } from '@angular/material/expansion';
 import { SortByRuntimeNamePipe } from './pipes/sort-by-runtime-name.pipe';
+import { DragDropModule } from '@angular/cdk/drag-drop';
 
 @NgModule({
     declarations: [
@@ -136,6 +138,7 @@ import { SortByRuntimeNamePipe } from 
'./pipes/sort-by-runtime-name.pipe';
         SpConfigurationBoxComponent,
         SelectDataRangeComponent,
         SelectDataMissingValuesComponent,
+        SidebarResizeComponent,
         LivePreviewLoadingComponent,
         LivePreviewTableComponent,
         LivePreviewErrorComponent,
@@ -175,6 +178,7 @@ import { SortByRuntimeNamePipe } from 
'./pipes/sort-by-runtime-name.pipe';
         MatProgressSpinnerModule,
         MatSort,
         TranslateModule.forChild({}),
+        DragDropModule,
         MarkdownModule.forRoot(),
     ],
     providers: [
@@ -211,6 +215,7 @@ import { SortByRuntimeNamePipe } from 
'./pipes/sort-by-runtime-name.pipe';
         PipelineElementHelpComponent,
         PipelineElementComponent,
         InputSchemaPanelComponent,
+        SidebarResizeComponent,
     ],
 })
 export class SharedUiModule {}
diff --git a/ui/projects/streampipes/shared-ui/src/public-api.ts 
b/ui/projects/streampipes/shared-ui/src/public-api.ts
index 5eccf65f77..ae6cdd29c1 100644
--- a/ui/projects/streampipes/shared-ui/src/public-api.ts
+++ b/ui/projects/streampipes/shared-ui/src/public-api.ts
@@ -52,6 +52,7 @@ export * from 
'./lib/components/pipeline-element-runtime-info/pipeline-element-r
 export * from 
'./lib/components/pipeline-element-documentation/pipeline-element-documentation.component';
 export * from './lib/components/pipeline-element/pipeline-element.component';
 export * from 
'./lib/components/input-schema-panel/input-schema-panel.component';
+export * from './lib/components/sidebar-resize/sidebar-resize.component';
 
 export * from './lib/models/sp-navigation.model';
 
diff --git 
a/ui/src/app/data-explorer-shared/components/charts/base/echarts-widget.component.ts
 
b/ui/src/app/data-explorer-shared/components/charts/base/echarts-widget.component.ts
index dd8895db5a..e6e5629f55 100644
--- 
a/ui/src/app/data-explorer-shared/components/charts/base/echarts-widget.component.ts
+++ 
b/ui/src/app/data-explorer-shared/components/charts/base/echarts-widget.component.ts
@@ -16,7 +16,7 @@
  *
  */
 
-import { Component, OnInit } from '@angular/core';
+import { Component, inject, OnInit } from '@angular/core';
 import {
     DataExplorerField,
     DataExplorerWidgetModel,
@@ -28,6 +28,7 @@ import { ECharts } from 'echarts/core';
 import { EChartsOption } from 'echarts';
 import { Subject, Subscription } from 'rxjs';
 import { debounceTime } from 'rxjs/operators';
+import { ResizeEchartsService } from 
'../../../services/resize-echarts.service';
 
 @Component({
     selector: 'sp-data-explorer-echarts-widget',
@@ -48,15 +49,24 @@ export class SpEchartsWidgetComponent<T extends 
DataExplorerWidgetModel>
     latestData: SpQueryResult[];
 
     renderSubject = new Subject<void>();
-    renderSubjectSubscription: Subscription;
+    renderSubject$: Subscription;
+    resizeEcharts$: Subscription;
     renderer: SpEchartsRenderer<T>;
 
+    resizeEchartsService = inject(ResizeEchartsService);
+
     widgetTypeLabel: string;
 
     ngOnInit(): void {
         super.ngOnInit();
         this.renderer = this.getRenderer();
-        this.renderSubjectSubscription = this.renderSubject
+        this.resizeEcharts$ =
+            this.resizeEchartsService.echartsResizeSubject.subscribe(width => {
+                this.currentWidth = width - this.widthOffset;
+                this.applySize(this.currentWidth, this.currentHeight);
+                this.refreshView();
+            });
+        this.renderSubject$ = this.renderSubject
             .pipe(debounceTime(300))
             .subscribe(() => {
                 this.renderChartOptions(this.latestData);
@@ -124,7 +134,8 @@ export class SpEchartsWidgetComponent<T extends 
DataExplorerWidgetModel>
 
     public cleanupSubscriptions(): void {
         super.cleanupSubscriptions();
-        this.renderSubjectSubscription.unsubscribe();
+        this.resizeEcharts$?.unsubscribe();
+        this.renderSubject$?.unsubscribe();
     }
 
     getRenderer(): SpEchartsRenderer<T> {
diff --git 
a/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.scss
 b/ui/src/app/data-explorer-shared/services/resize-echarts.service.ts
similarity index 60%
copy from 
ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.scss
copy to ui/src/app/data-explorer-shared/services/resize-echarts.service.ts
index b8ebed30f9..d930b02676 100644
--- 
a/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.scss
+++ b/ui/src/app/data-explorer-shared/services/resize-echarts.service.ts
@@ -16,44 +16,14 @@
  *
  */
 
-.fixed-height {
-    height: 50px;
-}
-
-.data-explorer-options {
-    padding: 0px;
-}
-
-.data-explorer-options-item {
-    display: inline;
-    margin-right: 10px;
-}
-
-.m-20 {
-    margin: 20px;
-}
+import { Injectable } from '@angular/core';
+import { Subject } from 'rxjs';
 
-.h-100 {
-    height: 100%;
-}
-
-.dashboard-grid {
-    display: flex;
-    flex-direction: column;
-    flex: 1 1 100%;
-}
-
-.designer-panel-container {
-    width: 100%;
-    height: 100%;
-}
-
-.designer-panel {
-    width: 450px;
-    border: 1px solid var(--color-tab-border);
-}
+@Injectable({ providedIn: 'root' })
+export class ResizeEchartsService {
+    public echartsResizeSubject: Subject<number> = new Subject<number>();
 
-.widget-title-text {
-    white-space: nowrap;
-    margin-right: 12px;
+    public notify(width: number): void {
+        this.echartsResizeSubject.next(width);
+    }
 }
diff --git 
a/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.html
 
b/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.html
index 2f3c30bf4c..ac7c19b8c4 100644
--- 
a/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.html
+++ 
b/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.html
@@ -46,18 +46,25 @@
         >
             <mat-drawer
                 [opened]="editMode"
+                [style.width.px]="drawerWidth"
                 mode="side"
                 position="end"
                 class="designer-panel"
             >
-                <div fxLayout="column" fxFlex="100">
-                    <sp-data-explorer-designer-panel
-                        [currentlyConfiguredWidget]="dataView"
-                        [dataLakeMeasure]="dataLakeMeasure"
-                        fxFlex="100"
-                    >
-                    </sp-data-explorer-designer-panel>
-                </div>
+                <sp-sidebar-resize
+                    [minWidth]="450"
+                    [maxWidth]="1000"
+                    (widthChanged)="onWidthChanged($event)"
+                >
+                    <div fxLayout="column" fxFlex="100">
+                        <sp-data-explorer-designer-panel
+                            [currentlyConfiguredWidget]="dataView"
+                            [dataLakeMeasure]="dataLakeMeasure"
+                            fxFlex="100"
+                        >
+                        </sp-data-explorer-designer-panel>
+                    </div>
+                </sp-sidebar-resize>
             </mat-drawer>
             <mat-drawer-content class="h-100 dashboard-grid">
                 <div #panel fxFlex="100" fxLayout="column">
diff --git 
a/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.scss
 
b/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.scss
index b8ebed30f9..b286235804 100644
--- 
a/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.scss
+++ 
b/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.scss
@@ -49,8 +49,11 @@
 }
 
 .designer-panel {
-    width: 450px;
     border: 1px solid var(--color-tab-border);
+    width: auto;
+    flex: 0 0 auto;
+    display: inline-block;
+    overflow-x: hidden;
 }
 
 .widget-title-text {
diff --git 
a/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.ts
 
b/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.ts
index 3e27ab7404..3d0e5cb82a 100644
--- 
a/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.ts
+++ 
b/ui/src/app/data-explorer/components/chart-view/data-explorer-chart-view.component.ts
@@ -16,7 +16,14 @@
  *
  */
 
-import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
+import {
+    Component,
+    ElementRef,
+    inject,
+    OnInit,
+    signal,
+    ViewChild,
+} from '@angular/core';
 import {
     ChartService,
     DataExplorerWidgetModel,
@@ -40,6 +47,7 @@ import { Observable, of } from 'rxjs';
 import { MatDialog } from '@angular/material/dialog';
 import { map } from 'rxjs/operators';
 import { TranslateService } from '@ngx-translate/core';
+import { ResizeEchartsService } from 
'../../../data-explorer-shared/services/resize-echarts.service';
 
 @Component({
     selector: 'sp-data-explorer-data-view',
@@ -57,6 +65,10 @@ export class DataExplorerChartViewComponent
     originalDataView: DataExplorerWidgetModel;
     dataLakeMeasure: DataLakeMeasure;
     gridsterItemComponent: any;
+    drawerWidth = 450;
+    panelWidth = '100%';
+
+    resizeEchartsService = inject(ResizeEchartsService);
 
     @ViewChild('panel', { static: false }) outerPanel: ElementRef;
 
@@ -225,4 +237,13 @@ export class DataExplorerChartViewComponent
             this.dataView,
         );
     }
+
+    onWidthChanged(newWidth: number) {
+        this.drawerWidth = newWidth;
+        setTimeout(() => {
+            this.resizeEchartsService.notify(
+                this.outerPanel.nativeElement.offsetWidth,
+            );
+        }, 100);
+    }
 }

Reply via email to