Fixing null issue and adding zooming 87/95487/1
authorrokenny <ronan.kenny@est.tech>
Wed, 11 Sep 2019 12:14:52 +0000 (13:14 +0100)
committerrokenny <ronan.kenny@est.tech>
Wed, 11 Sep 2019 12:18:37 +0000 (13:18 +0100)
Change-Id: I6a3ff57b6131c10965400beac43c4c8101b24397
Issue-ID: SO-2274
Signed-off-by: rokenny <ronan.kenny@est.tech>
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/app.module.ts
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/details/details.component.html
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/details/details.component.scss
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/details/details.component.ts
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/http-error-handler.service.ts

index 71294bf..5adfc04 100644 (file)
@@ -19,7 +19,7 @@ See the License for the specific language governing permissions and
 SPDX-License-Identifier: Apache-2.0
 ============LICENSE_END=========================================================
 
-@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+@authors: ronan.kenny@est.tech, waqas.ikram@est.tech
 */
 
 import { BrowserModule } from '@angular/platform-browser';
@@ -35,13 +35,13 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
 import { DetailsComponent } from './details/details.component';
 import { ToastrNotificationService } from './toastr-notification-service.service';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-import { MatFormFieldModule, MatInputModule, MatTableModule, MatTabsModule, MatSelectModule, MatNativeDateModule, MatDatepickerModule, MatCardModule, MatPaginatorModule, MatSortModule } from '@angular/material';
+import { MatFormFieldModule, MatInputModule, MatTableModule, MatTabsModule, MatSelectModule, MatNativeDateModule, MatDatepickerModule, MatCardModule, MatPaginatorModule, MatSortModule, MatIconModule } from '@angular/material';
 import { NgxSpinnerModule } from 'ngx-spinner';
 import { RouterModule, Routes } from '@angular/router';
 import { APP_BASE_HREF } from '@angular/common';
 import { LoginComponent } from './login/login.component';
-import {BasicAuthInterceptor} from "./basic-auth.interceptor";
-import {ErrorInterceptor} from "./error.interceptor";
+import { BasicAuthInterceptor } from "./basic-auth.interceptor";
+import { ErrorInterceptor } from "./error.interceptor";
 
 @NgModule({
   declarations: [
@@ -70,6 +70,7 @@ import {ErrorInterceptor} from "./error.interceptor";
     RouterModule,
     MatPaginatorModule,
     MatSortModule,
+    MatIconModule,
     RouterModule.forRoot([]),
     ReactiveFormsModule
   ],
index a98095c..8ad955f 100644 (file)
@@ -17,12 +17,23 @@ See the License for the specific language governing permissions and
 SPDX-License-Identifier: Apache-2.0
 ============LICENSE_END=========================================================
 
-@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+@authors: ronan.kenny@est.tech, waqas.ikram@est.tech
 -->
 
 <div class="completeForm">
   <div class="topCanvas">
-    <section class="canvas" id="canvas"></section>
+    <div class="navigation">
+      <button class="zoomButton" mat-icon-button title="zoom in" (click)="zoomIn()">
+        <mat-icon>zoom_in</mat-icon>
+      </button>
+      <button class="zoomButton" mat-icon-button title="zoom out" (click)="zoomOut()">
+        <mat-icon>zoom_out</mat-icon>
+      </button>
+      <button class="zoomButton" mat-icon-button title="reset zoom" (click)="resetZoom()">
+        <mat-icon>all_out</mat-icon>
+      </button>
+    </div>
+    <div #canvas class="canvas" id="canvas"></div>
     <mat-card class="besideCanvas" id="besideCanvas">
       <mat-card-title>Process Information</mat-card-title>
       <br />
index 2789723..b96fe4a 100644 (file)
@@ -17,23 +17,39 @@ See the License for the specific language governing permissions and
 SPDX-License-Identifier: Apache-2.0
 ============LICENSE_END=========================================================
 
-@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+@authors: ronan.kenny@est.tech, waqas.ikram@est.tech
 */
 #canvas {
   background: white;
   padding: 0;
-  margin: 0;
+  margin-left: -43px;
   width: 70%;
   height: 470px;
   margin-top: 0;
-  box-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);
+  box-shadow: 0 8px 10px 1px rgba(0,0,0,.2);
+}
+
+.navigation {
+  background: #e6e6e6;
+  width: 40px;
+  box-shadow: -5px 8px 10px 1px rgba(0,0,0,.2);
+  height: 470px;
+  border: 1px;
+  border-color: black;
+  position: relative;
+}
+
+.zoomButton {
+  padding-top: 8px;
+  background: none;
+  border: none;
 }
 
 #besideCanvas {
   background: white;
   padding-left: 20px;
   margin: 0;
-  width: 28%;
+  width: 25%;
   height: 470px;
   margin-top: 0;
   box-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);
index 7106a87..a42fa3f 100644 (file)
@@ -17,7 +17,7 @@ See the License for the specific language governing permissions and
 SPDX-License-Identifier: Apache-2.0
 ============LICENSE_END=========================================================
 
-@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+@authors: ronan.kenny@est.tech, waqas.ikram@est.tech
 */
 
 import { Component, OnInit } from '@angular/core';
@@ -34,6 +34,7 @@ import { MatTabsModule } from '@angular/material/tabs';
 import { VariableInstance } from '../model/variableInstance.model';
 import { ToastrNotificationService } from '../toastr-notification-service.service';
 import { NgxSpinnerService } from 'ngx-spinner';
+import { ElementRef, ViewChild } from '@angular/core';
 
 @Component({
   selector: 'app-details',
@@ -43,6 +44,9 @@ import { NgxSpinnerService } from 'ngx-spinner';
 })
 
 export class DetailsComponent implements OnInit {
+
+  @ViewChild("canvas") elementReference: ElementRef;
+
   bpmnViewer: any;
 
   processInstanceID: string;
@@ -82,7 +86,8 @@ export class DetailsComponent implements OnInit {
       async (data: ProcessDefinitionDetail) => {
         this.processDefinition = data;
         console.log(data);
-        await this.displayCamundaflow(this.processDefinition.processDefinitionXml, this.activityInstance, this.router);
+        await this.displayCamundaflow(this.processDefinition.processDefinitionXml, this.activityInstance,
+          this.router, this.spinner, this.popup);
       }, error => {
         console.log(error);
         this.popup.error("Unable to get process definition for id: " + procDefId + " Error code:" + error.status);
@@ -104,30 +109,53 @@ export class DetailsComponent implements OnInit {
       });
   }
 
-  displayCamundaflow(bpmnXml, activities: ActivityInstance[], r: Router) {
-    this.spinner.show();
+  displayCamundaflow(bpmnXml, activities: ActivityInstance[], router: Router,
+    spinner: NgxSpinnerService, popup: ToastrNotificationService) {
+    spinner.show();
 
     this.bpmnViewer.importXML(bpmnXml, (error) => {
       if (error) {
         console.error('Unable to load BPMN flow ', error);
-        this.popup.error('Unable to load BPMN flow ');
-        this.spinner.hide();
+        popup.error('Unable to load BPMN flow ');
+        spinner.hide();
       } else {
-        this.spinner.hide();
-        var canvas = this.bpmnViewer.get('canvas');
+        spinner.hide();
+        let canvas = this.bpmnViewer.get('canvas');
         var eventBus = this.bpmnViewer.get('eventBus');
-        eventBus.on('element.click', function(e) {
+        var elementRegistry = this.bpmnViewer.get('elementRegistry');
+        var overlays = this.bpmnViewer.get('overlays');
 
-          activities.forEach(a => {
-            if (a.activityId == e.element.id && a.calledProcessInstanceId !== null) {
-              console.log("will drill down to : " + a.calledProcessInstanceId);
-              r.navigate(['/details/' + a.calledProcessInstanceId]);
-              this.spinner.show();
-            }
-          });
+        activities.forEach(a => {
+          if (a.calledProcessInstanceId !== null) {
+            var element = elementRegistry.get(a.activityId);
+            let newNode = document.createElement('div');
+            newNode.className = 'highlight-overlay';
+            newNode.id = element.id;
+            newNode.style.width = element.width + "px";
+            newNode.style.height = element.height + "px";
+            newNode.style.cursor = "pointer";
+
+            overlays.add(a.activityId, {
+              position: {
+                top: -5,
+                left: -5
+              },
+              html: newNode
+            });
+
+            newNode.addEventListener('click', function(e) {
+              console.log("clicked on: " + e.srcElement.id)
+              activities.forEach(a => {
+                if (a.activityId == e.srcElement.id && a.calledProcessInstanceId !== null) {
+                  console.log("will drill down to : " + a.calledProcessInstanceId);
+                  router.navigate(['/details/' + a.calledProcessInstanceId]);
+                }
+              });
+            });
+          }
         });
         // zoom to fit full viewport
-        canvas.zoom('fit-viewport');
+        canvas.zoom('fit-viewport', 'auto');
         activities.forEach(a => {
           canvas.addMarker(a.activityId, 'highlight');
         });
@@ -135,6 +163,26 @@ export class DetailsComponent implements OnInit {
     });
   }
 
+  zoomIn() {
+    this.bpmnViewer.get('zoomScroll').zoom(1, {
+      x: this.elementReference.nativeElement.offsetWidth / 2,
+      y: this.elementReference.nativeElement.offsetHeight / 2
+    });
+  }
+
+  zoomOut() {
+    this.bpmnViewer.get('zoomScroll').zoom(-1, {
+      x: this.elementReference.nativeElement.offsetWidth / 2,
+      y: this.elementReference.nativeElement.offsetHeight / 2
+    });
+  }
+  resetZoom() {
+    let canvas = this.bpmnViewer.get('canvas');
+    canvas.resized();
+    canvas.zoom('fit-viewport', 'auto');
+
+  }
+
   getVarInst(procInstId: string) {
     this.data.getVariableInstance(procInstId).subscribe(
       (data: VariableInstance[]) => {
index 16d274f..b22fa6e 100644 (file)
@@ -17,7 +17,7 @@ See the License for the specific language governing permissions and
 SPDX-License-Identifier: Apache-2.0\r
 ============LICENSE_END=========================================================\r
 \r
-@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com\r
+@authors: ronan.kenny@est.tech, waqas.ikram@est.tech\r
 */\r
 \r
 import { Injectable } from '@angular/core';\r
@@ -44,9 +44,9 @@ export class HttpErrorHandlerService {
         this.popup.error("Internal Service Error occured for operation: " + operation + " please check backend service log. status code: " + error.status);\r
       }\r
       console.error(\r
-        'Backend returned code ${error.status}, ' +\r
-        'body was: ${error.error}');\r
-      return throwError(error.error || "Internal Service Error occured for operation: " + operation + " please check backend service log. status code: " + error.status);\r
+        'Backend returned status code: ', error.status + ' from URL ' + url);\r
+      return throwError(error.error || "Internal Service Error occured for operation: " +\r
+        operation + ". Please check backend service log. Status code: " + error.status);\r
     };\r
 \r
   }\r