You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ri...@apache.org on 2020/06/14 22:04:36 UTC

[incubator-streampipes] 02/04: [STREAMPIPES-145] Migrate pipeline element filter

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

riemer pushed a commit to branch STREAMPIPES-145
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git

commit dbcca294a090d3f1097268ce27697d73edd72d62
Author: Dominik Riemer <ri...@fzi.de>
AuthorDate: Sun Jun 14 22:07:34 2020 +0200

    [STREAMPIPES-145] Migrate pipeline element filter
---
 .../pipeline-element-icon-stand.component.html     | 59 ++++----------
 ... => pipeline-element-icon-stand.component.scss} | 10 ++-
 .../pipeline-element-icon-stand.component.ts       | 94 ++++++++++++++--------
 ui/src/app/editor-v2/editor.component.html         |  2 +-
 ui/src/app/editor-v2/editor.component.ts           |  3 -
 ui/src/app/editor-v2/services/editor.service.ts    | 12 +++
 6 files changed, 99 insertions(+), 81 deletions(-)

diff --git a/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.html b/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.html
index 046042e..794d17f 100644
--- a/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.html
+++ b/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.html
@@ -22,61 +22,36 @@
         <div fxLayoutAlign="start center" fxLayout="row">
             <div fxLayout="row" style="margin-right: 5px">
                 <i class="material-icons">search</i>
-                <input type="text" ng-model="elementFilter" placeholder="Find Element"
+                <input type="text" (keyup)="applyFilter()" [(ngModel)]="elementFilter" placeholder="Find Element"
                        style="background-color:#f6f6f6;border: none;border-bottom: solid 2px rgb(27, 20, 100);">&nbsp;
             </div>
             <div fxLayout="row">
-                <button mat-button [matMenuTriggerFor]="menu"><i class="material-icons">list</i>Filter by category</button>
+                <button mat-button [matMenuTriggerFor]="menu"><div class="menu-text-color"><i class="material-icons">list</i>&nbsp;Filter by category</div></button>
                 <mat-menu #menu="matMenu">
-                    <button mat-menu-item>
-                        <i class="material-icons">done</i>&nbsp;Select all
+                    <button mat-menu-item (click)="selectAllOptions()">
+                        <div class="menu-text-color"><i class="material-icons">done</i>&nbsp;Select all</div>
                     </button>
-                    <button mat-menu-item>
-                        <i class="material-icons">clear</i>&nbsp;Deselect all
+                    <button mat-menu-item (click)="deselectAllOptions()">
+                        <div class="menu-text-color"><i class="material-icons">clear</i>&nbsp;Deselect all</div>
+                    </button>
+                    <mat-divider></mat-divider>
+                    <button (click)="toggleOption(option)" mat-menu-item *ngFor="let option of currentCategories">
+                        <div class="menu-text-color" *ngIf="optionSelected(option)">
+                            <i class="material-icons">visibility</i>&nbsp;{{option.label}}
+                        </div>
+                        <div  class="menu-text-color" *ngIf="!optionSelected(option)">
+                            <i class="material-icons">visibility_off</i>&nbsp;{{option.label}}
+                        </div>
                     </button>
                 </mat-menu>
-<!--                <md-menu-bar>-->
-<!--                    <md-menu>-->
-<!--                        <button ng-click="$mdOpenMenu()" class="sp-accent">-->
-<!--                            <md-icon md-svg-icon="action:ic_view_list_24px"-->
-<!--                                     class="sp-accent"></md-icon>-->
-<!--                            Filter by category-->
-<!--                        </button>-->
-<!--                        <md-menu-content>-->
-<!--                            <md-menu-item class="md-indent">-->
-<!--                                <md-icon md-svg-icon="action:ic_done_24px"-->
-<!--                                         class="sp-accent"></md-icon>-->
-<!--                                <md-button ng-click="ctrl.selectAllOptions()">&nbsp;Select all</md-button>-->
-<!--                            </md-menu-item>-->
-<!--                            <md-menu-item class="md-indent">-->
-<!--                                <md-icon md-svg-icon="content:ic_clear_24px"-->
-<!--                                         class="sp-accent"></md-icon>-->
-<!--                                <md-button ng-click="ctrl.deselectAllOptions()">&nbsp;Deselect all</md-button>-->
-<!--                            </md-menu-item>-->
-<!--                            <md-menu-divider></md-menu-divider>-->
-<!--                            <div ng-repeat="option in ctrl.availableOptions[ctrl.activeType] | orderBy: 'label'">-->
-<!--                                <md-menu-item class="md-indent">-->
-<!--                                    <md-icon md-svg-icon="action:ic_visibility_24px"-->
-<!--                                             class="sp-accent"-->
-<!--                                             ng-if="ctrl.optionSelected(option)"></md-icon>-->
-<!--                                    <md-icon md-svg-icon="action:ic_visibility_off_24px"-->
-<!--                                             class="sp-accent"-->
-<!--                                             ng-if="!ctrl.optionSelected(option)"></md-icon>-->
-<!--                                    <md-button ng-click="ctrl.toggleFilter(option)">&nbsp;{{option.label}}-->
-<!--                                    </md-button>-->
-<!--                                </md-menu-item>-->
-<!--                            </div>-->
-<!--                        </md-menu-content>-->
-<!--                    </md-menu>-->
-<!--                </md-menu-bar>-->
             </div>
         </div>
     </div>
 </div>
-<div flex id="editor-icon-stand" class="icon-stand" *ngIf="currentElements">
+<div flex id="editor-icon-stand" class="icon-stand" *ngIf="currentlyFilteredElements">
     <span id="{{ element.appId }}" (mouseenter)="updateMouseOver(element.name)"
           (mouseleave)="updateMouseOver('')"
-          *ngFor="let element of currentElements"
+          *ngFor="let element of currentlyFilteredElements"
           class="draggable-icon tt"
           [attr.data-pe]="element.elementId"
           [ngClass]="activeCssClass">
diff --git a/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.css b/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.scss
similarity index 84%
rename from ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.css
rename to ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.scss
index 41ecef0..a2714f7 100644
--- a/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.css
+++ b/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.scss
@@ -14,4 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
- */
\ No newline at end of file
+ */
+
+@import '../../../../scss/_variables.scss';
+
+.menu-text-color {
+    color: $sp-color-accent;
+    display: flex;
+    align-items: center;
+}
\ No newline at end of file
diff --git a/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.ts b/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.ts
index 2b1f788..5e74d7b 100644
--- a/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.ts
+++ b/ui/src/app/editor-v2/components/pipeline-element-icon-stand/pipeline-element-icon-stand.component.ts
@@ -17,25 +17,28 @@
  */
 
 import {Component, Input, OnInit,} from "@angular/core";
-import * as angular from "angular";
 import {RestApi} from "../../../services/rest-api.service";
 import {PipelineElementType, PipelineElementUnion} from "../../model/editor.model";
 import {PipelineElementTypeUtils} from "../../utils/editor.utils";
 import {EditorService} from "../../services/editor.service";
+import {zip} from "rxjs";
 
 
 @Component({
     selector: 'pipeline-element-icon-stand',
     templateUrl: './pipeline-element-icon-stand.component.html',
-    styleUrls: ['./pipeline-element-icon-stand.component.css']
+    styleUrls: ['./pipeline-element-icon-stand.component.scss']
 })
 export class PipelineElementIconStandComponent implements OnInit {
 
-    @Input()
-    currentElements: PipelineElementUnion[];
 
-    elementFilter: string;
-    availableOptions: any = [];
+    _currentElements: PipelineElementUnion[];
+
+    currentlyFilteredElements: PipelineElementUnion[];
+
+    elementFilter: string = "";
+    allCategories: any = [];
+    currentCategories: any = [];
     selectedOptions: any = [];
 
     _activeType: PipelineElementType;
@@ -49,7 +52,7 @@ export class PipelineElementIconStandComponent implements OnInit {
     }
 
     ngOnInit(): void {
-        this.loadOptions(this.activeType);
+        this.loadOptions();
     }
 
     ngAfterViewInit() {
@@ -64,62 +67,85 @@ export class PipelineElementIconStandComponent implements OnInit {
         this.currentElementName = elementAppId;
     }
 
-    loadOptions(type?) {
-        this.RestApi.getEpCategories()
-            .then(msg => {
-                let s = msg;
-                this.handleCategoriesSuccess("stream", s);
-                this.handleCategoriesSuccess("set", s);
+    loadOptions() {
+        zip(this.EditorService.getEpCategories(),
+            this.EditorService.getEpaCategories(),
+            this.EditorService.getEcCategories()).subscribe((results) => {
+                this.allCategories[PipelineElementType.DataStream] = results[0];
+                this.allCategories[PipelineElementType.DataSet] = results[0];
+                this.allCategories[PipelineElementType.DataProcessor] = results[1];
+                this.allCategories[PipelineElementType.DataSink] = results[2];
+                this.currentCategories = this.allCategories[0];
+                this.selectedOptions = [...this.currentCategories];
             });
-
-        this.RestApi.getEpaCategories()
-            .then(s => this.handleCategoriesSuccess("sepa", s));
-
-        this.RestApi.getEcCategories()
-            .then(s => this.handleCategoriesSuccess("action", s));
-
     };
 
-    getOptions(type) {
-        this.selectAllOptions();
-        //return this.availableOptions[type];
+    applyFilter() {
+        this.currentlyFilteredElements = this.currentElements.filter(el => {
+            return this.matchesText(el) && this.matchesCategory(el);
+        })
     }
 
+    matchesText(el: PipelineElementUnion): boolean {
+        return this.elementFilter === "" || el.name.includes(this.elementFilter);
+    }
 
-    handleCategoriesSuccess(type, result) {
-        this.availableOptions[type] = result.data;
-        this.selectAllOptions();
+    matchesCategory(el: PipelineElementUnion): boolean {
+        return this._activeType === PipelineElementType.DataStream ||
+            this._activeType === PipelineElementType.DataSet ?
+            this.selectedOptions.some(c => el.category.some(cg => c.type === cg)) :
+            this.selectedOptions.some(c => el.category.some(cg => c.code === cg));
     }
 
-    toggleFilter(option) {
-        this.selectedOptions = [];
-        this.selectedOptions.push(option.type);
+    toggleOption(option) {
+        if (this.optionSelected(option)) {
+            this.selectedOptions.splice(option, 1);
+        } else {
+            this.selectedOptions.push(option);
+        }
+        this.applyFilter();
     }
 
     optionSelected(option) {
-        return this.selectedOptions.indexOf(option.type) > -1;
+        return this._activeType === PipelineElementType.DataStream ||
+        this._activeType === PipelineElementType.DataSet ?
+            this.selectedOptions.map(o => o.type).indexOf(option.type) > -1 :
+            this.selectedOptions.map(o => o.code).indexOf(option.code) > -1;
     }
 
     selectAllOptions() {
-        this.selectedOptions = [];
-        angular.forEach(this.availableOptions[this.activeType], o => {
-            this.selectedOptions.push(o.type);
-        });
+        this.selectedOptions = [...this.currentCategories];
+        this.applyFilter();
     }
 
     deselectAllOptions() {
         this.selectedOptions = [];
+        this.applyFilter();
     }
 
     @Input()
     set activeType(value: PipelineElementType) {
         this._activeType = value;
+        if (this.allCategories.length > 0) {
+            this.currentCategories = this.allCategories[this._activeType];
+            this.selectedOptions = [...this.currentCategories];
+        }
         this.activeCssClass = this.makeActiveCssClass(value);
         setTimeout(() => {
             this.makeDraggable();
         })
     };
 
+    @Input()
+    set currentElements(value: PipelineElementUnion[]) {
+        this._currentElements = value;
+        this.currentlyFilteredElements = this._currentElements;
+    }
+
+    get currentElements() {
+        return this._currentElements;
+    }
+
     makeActiveCssClass(elementType: PipelineElementType): string {
         return PipelineElementTypeUtils.toCssShortHand(elementType);
     }
diff --git a/ui/src/app/editor-v2/editor.component.html b/ui/src/app/editor-v2/editor.component.html
index 23f9e22..3edf415 100644
--- a/ui/src/app/editor-v2/editor.component.html
+++ b/ui/src/app/editor-v2/editor.component.html
@@ -34,7 +34,7 @@
              style="background-color:#f6f6f6;padding:0px;border-bottom:1px solid #ffffff">
             <pipeline-element-icon-stand [activeType]="activeType"
                                          [currentElements]="currentElements"
-                                         element-filter="ctrl.elementFilter" *ngIf="allElementsLoaded">
+                                         *ngIf="allElementsLoaded">
             </pipeline-element-icon-stand>
         </div>
         <pipeline-assembly [rawPipelineModel]="rawPipelineModel" [allElements]="allElements"
diff --git a/ui/src/app/editor-v2/editor.component.ts b/ui/src/app/editor-v2/editor.component.ts
index 790fb1f..2251161 100644
--- a/ui/src/app/editor-v2/editor.component.ts
+++ b/ui/src/app/editor-v2/editor.component.ts
@@ -129,8 +129,5 @@ export class EditorComponent implements OnInit {
         this.activeType = this.tabs[index].type;
         this.currentElements = this.allElements
             .filter(pe => pe instanceof PipelineElementTypeUtils.toType(this.activeType));
-        console.log(this.currentElements);
     }
-
-
 }
diff --git a/ui/src/app/editor-v2/services/editor.service.ts b/ui/src/app/editor-v2/services/editor.service.ts
index c6be960..7df13b7 100644
--- a/ui/src/app/editor-v2/services/editor.service.ts
+++ b/ui/src/app/editor-v2/services/editor.service.ts
@@ -59,6 +59,18 @@ export class EditorService {
         return this.http.get(this.platformServicesCommons.authUserBasePath() + "/pipeline-cache");
     }
 
+    getEpCategories() {
+        return this.http.get(this.platformServicesCommons.unauthenticatedBasePath + "/categories/ep");
+    }
+
+    getEpaCategories() {
+        return this.http.get(this.platformServicesCommons.unauthenticatedBasePath + "/categories/epa");
+    }
+
+    getEcCategories() {
+        return this.http.get(this.platformServicesCommons.unauthenticatedBasePath + "/categories/ec");
+    }
+
     updateCachedPipeline(rawPipelineModel: any) {
         return this.http.post(this.platformServicesCommons.authUserBasePath() + "/pipeline-cache", rawPipelineModel);
     }