aboutsummaryrefslogtreecommitdiffstats
path: root/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src
diff options
context:
space:
mode:
Diffstat (limited to 'so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src')
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app-routing.module.ts46
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.html29
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.scss0
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.spec.ts57
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.ts33
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.module.ts77
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/data.service.spec.ts110
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/data.service.ts95
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.html112
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.scss88
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.spec.ts218
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.ts224
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.html205
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.scss130
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.spec.ts178
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.ts140
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.constant.ts41
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/http-error-handler.service.spec.ts44
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/http-error-handler.service.ts53
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/SearchRequest.model.ts42
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/activityInstance.model.ts32
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/bpmnInfraRequest.model.ts32
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/processDefinition.model.ts26
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/processInstance.model.ts28
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/processInstanceId.model.ts25
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/searchData.model.spec.ts78
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/searchData.model.ts107
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/variableInstance.model.ts27
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.html29
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.scss44
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.spec.ts61
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.ts39
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/ssl/localhost.crt23
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/ssl/localhost.key28
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/toastr-notification-service.service.spec.ts43
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/toastr-notification-service.service.ts59
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.html25
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.scss59
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.spec.ts51
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.ts35
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/assets/.gitkeep0
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/browserslist9
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/environments/environment.prod.ts3
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/environments/environment.ts28
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/favicon.pngbin0 -> 728 bytes
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/index.html42
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/karma.conf.js31
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/main.ts34
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/polyfills.ts80
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/styles.scss73
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/test.ts40
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/tsconfig.app.json12
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/tsconfig.spec.json19
-rw-r--r--so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/tslint.json17
54 files changed, 3161 insertions, 0 deletions
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app-routing.module.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app-routing.module.ts
new file mode 100644
index 0000000..428998d
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app-routing.module.ts
@@ -0,0 +1,46 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { HomeComponent } from './home/home.component';
+import { DetailsComponent } from './details/details.component';
+
+const routes: Routes = [
+ {
+ // Route to home page
+ path: '',
+ component: HomeComponent
+ },
+ {
+ // Route to page to show individual process based on ID
+ path: 'details/:id',
+ component: DetailsComponent
+ }
+];
+
+@NgModule({
+ imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })],
+ exports: [RouterModule]
+})
+
+export class AppRoutingModule { }
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.html b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.html
new file mode 100644
index 0000000..79c07dd
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.html
@@ -0,0 +1,29 @@
+<!--
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+-->
+
+<app-topbar></app-topbar>
+<div id="container">
+ <app-sidebar></app-sidebar>
+ <div id="content">
+ <router-outlet></router-outlet>
+ </div>
+</div>
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.scss b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.scss
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.spec.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.spec.ts
new file mode 100644
index 0000000..82e32ea
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.spec.ts
@@ -0,0 +1,57 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { TestBed, async } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { AppComponent } from './app.component';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+
+describe('AppComponent', () => {
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ RouterTestingModule
+ ],
+ declarations: [
+ AppComponent
+ ],
+ schemas: [
+ CUSTOM_ELEMENTS_SCHEMA
+ ],
+ }).compileComponents();
+ }));
+
+ // Ensure creation of SO Monitoring application
+ it('application should be created', async(() => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ expect(app).toBeTruthy();
+ }));
+
+
+ // Ensure application title is "SO Monitor"
+ it(`should have title 'SO Monitor'`, async(() => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ expect(app.title).toEqual('SO Monitor');
+ }));
+});
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.ts
new file mode 100644
index 0000000..a95e4c2
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.component.ts
@@ -0,0 +1,33 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-root',
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.scss']
+})
+
+export class AppComponent {
+ title = 'SO Monitor';
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.module.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.module.ts
new file mode 100644
index 0000000..75be395
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/app.module.ts
@@ -0,0 +1,77 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@est.tech, waqas.ikram@est.tech
+*/
+
+import { BrowserModule } from '@angular/platform-browser';
+import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+
+import { AppRoutingModule } from './app-routing.module';
+import { AppComponent } from './app.component';
+import { SidebarComponent } from './sidebar/sidebar.component';
+import { TopbarComponent } from './topbar/topbar.component';
+import { HomeComponent } from './home/home.component';
+import { HttpClientModule } from '@angular/common/http';
+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, MatIconModule } from '@angular/material';
+import { NgxSpinnerModule } from 'ngx-spinner';
+import { RouterModule, Routes } from '@angular/router';
+import { APP_BASE_HREF } from '@angular/common';
+
+@NgModule({
+ declarations: [
+ AppComponent,
+ SidebarComponent,
+ TopbarComponent,
+ HomeComponent,
+ DetailsComponent
+ ],
+ imports: [
+ BrowserModule,
+ AppRoutingModule,
+ HttpClientModule,
+ FormsModule,
+ MatTableModule,
+ MatTabsModule,
+ BrowserAnimationsModule,
+ MatSelectModule,
+ MatFormFieldModule,
+ MatInputModule,
+ MatDatepickerModule,
+ MatNativeDateModule,
+ MatCardModule,
+ NgxSpinnerModule,
+ RouterModule,
+ MatPaginatorModule,
+ MatSortModule,
+ MatIconModule,
+ RouterModule.forRoot([]),
+ ReactiveFormsModule
+ ],
+ schemas: [
+ CUSTOM_ELEMENTS_SCHEMA
+ ],
+ providers: [ToastrNotificationService],
+ bootstrap: [AppComponent]
+})
+export class AppModule { }
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/data.service.spec.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/data.service.spec.ts
new file mode 100644
index 0000000..1718678
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/data.service.spec.ts
@@ -0,0 +1,110 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { TestBed, inject } from '@angular/core/testing';
+
+import { DataService } from './data.service';
+import { HttpClient } from '@angular/common/http';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { async } from '@angular/core/testing';
+import { HttpClientModule } from '@angular/common/http';
+import { ToastrNotificationService } from './toastr-notification-service.service';
+import { environment } from '../environments/environment';
+
+class StubbedToastrNotificationService extends ToastrNotificationService {
+ toastrSettings() {
+ }
+}
+
+describe('DataService', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers: [DataService, { provide: ToastrNotificationService, useClass: StubbedToastrNotificationService }],
+ imports: [HttpClientTestingModule]
+ });
+ });
+
+ // Ensure creation of DataService component
+ it('component should be created', async(inject([HttpTestingController, DataService, ToastrNotificationService],
+ (httpClient: HttpTestingController, service: DataService, toastr: ToastrNotificationService) => {
+ expect(service).toBeTruthy();
+ })));
+
+ // Test getBpmnInfraRequest function making POST call
+ it('test getBpmnInfraRequest POST request', async(inject([HttpTestingController, DataService, ToastrNotificationService],
+ (httpClient: HttpTestingController, service: DataService, toastr: ToastrNotificationService) => {
+ service.getBpmnInfraRequest({}, 1, 2).subscribe(data => { });
+ var url = environment.soMonitoringBackendURL + 'v1/search?from=1&to=2';
+ const mockReq = httpClient.expectOne(url);
+ expect(mockReq.request.method).toEqual('POST');
+ mockReq.flush({});
+ })));
+
+ // Test getProcessInstanceId function making GET request to retrieve processInstanceID
+ it('test getProcessInstanceId GET request', async(inject([HttpTestingController, DataService, ToastrNotificationService],
+ (httpClient: HttpTestingController, service: DataService, toastr: ToastrNotificationService) => {
+ service.getProcessInstanceId("").subscribe(data => { });
+ var url = environment.soMonitoringBackendURL + 'process-instance-id/' + "";
+ const mockReq = httpClient.expectOne(url);
+ expect(mockReq.request.method).toEqual('GET');
+ mockReq.flush({});
+ })));
+
+ // Test getActivityInstance function making GET request to retrieve activityInstance
+ it('test getActivityInstance GET request', async(inject([HttpTestingController, DataService, ToastrNotificationService],
+ (httpClient: HttpTestingController, service: DataService, toastr: ToastrNotificationService) => {
+ service.getActivityInstance("").then(data => { });
+ var url = environment.soMonitoringBackendURL + 'activity-instance/' + "";
+ const mockReq = httpClient.expectOne(url);
+ expect(mockReq.request.method).toEqual('GET');
+ mockReq.flush({});
+ })));
+
+ // Test getProcessInstance function making GET request to retrieve processInstance
+ it('test getProcessInstance GET request', async(inject([HttpTestingController, DataService, ToastrNotificationService],
+ (httpClient: HttpTestingController, service: DataService, toastr: ToastrNotificationService) => {
+ service.getProcessInstance("");
+ var url = environment.soMonitoringBackendURL + 'process-instance/' + "";
+ const mockReq = httpClient.expectOne(url);
+ expect(mockReq.request.method).toEqual('GET');
+ })));
+
+ // Test getProcessDefinition function making GET request to retrieve processDefinition
+ it('test getProcessDefinition GET request', async(inject([HttpTestingController, DataService, ToastrNotificationService],
+ (httpClient: HttpTestingController, service: DataService, toastr: ToastrNotificationService) => {
+ service.getProcessDefinition("").subscribe(data => { });
+ var url = environment.soMonitoringBackendURL + 'process-definition/' + "";
+ const mockReq = httpClient.expectOne(url);
+ expect(mockReq.request.method).toEqual('GET');
+ mockReq.flush({});
+ })));
+
+ // Test getVariableInstance function making GET request to retrieve variableInstance
+ it('test getVariableInstance GET request', async(inject([HttpTestingController, DataService, ToastrNotificationService],
+ (httpClient: HttpTestingController, service: DataService, toastr: ToastrNotificationService) => {
+ service.getVariableInstance("").subscribe(data => { });
+ var url = environment.soMonitoringBackendURL + 'variable-instance/' + "";
+ const mockReq = httpClient.expectOne(url);
+ expect(mockReq.request.method).toEqual('GET');
+ mockReq.flush({});
+ })));
+});
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/data.service.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/data.service.ts
new file mode 100644
index 0000000..b391672
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/data.service.ts
@@ -0,0 +1,95 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { Injectable } from '@angular/core';
+import { HttpClient, HttpErrorResponse } from '@angular/common/http';
+import { BpmnInfraRequest } from './model/bpmnInfraRequest.model';
+import { catchError } from 'rxjs/operators';
+import { Observable } from 'rxjs';
+import { ProcessInstanceId } from './model/processInstanceId.model';
+import { environment } from '../environments/environment';
+import { HttpResponse } from '@angular/common/http';
+import { ProcessInstanceDetail } from './model/processInstance.model';
+import { HttpErrorHandlerService } from './http-error-handler.service';
+import { ActivityInstance } from './model/activityInstance.model';
+
+
+@Injectable({
+ providedIn: 'root'
+})
+export class DataService {
+
+ constructor(private http: HttpClient, private httpErrorHandlerService: HttpErrorHandlerService) { }
+
+ // HTTP POST call to running Spring Boot application
+ getBpmnInfraRequest(servInstId: {}, from: number, to: number): Observable<BpmnInfraRequest[]> {
+ var url = environment.soMonitoringBackendURL + 'v1/search?from=' + from + "&to=" + to;
+ return this.http.post<BpmnInfraRequest[]>(url, servInstId)
+ .pipe(
+ catchError(this.httpErrorHandlerService.handleError("POST", url))
+ );
+ }
+
+ // HTTP GET to return Process Instance using RequestID
+ getProcessInstanceId(requestId: string): Observable<HttpResponse<ProcessInstanceId>> {
+ var url = environment.soMonitoringBackendURL + 'process-instance-id/' + requestId;
+ console.log(requestId);
+ return this.http.get<ProcessInstanceId>(url, { observe: 'response' })
+ .pipe(
+ catchError(this.httpErrorHandlerService.handleError("GET", url))
+ );
+ }
+
+ // HTTP GET to return Activity instancs using ProcessInstanceID
+ getActivityInstance(processInstanceId: string): Promise<ActivityInstance[]> {
+ var url = environment.soMonitoringBackendURL + 'activity-instance/' + processInstanceId;
+ return this.http.get<ActivityInstance[]>(url)
+ .pipe(
+ catchError(this.httpErrorHandlerService.handleError("GET", url))
+ ).toPromise();
+ }
+
+ // HTTP GET to return Activity Instance using ProcessInstanceID
+ async getProcessInstance(processInstanceId: string): Promise<ProcessInstanceDetail> {
+ var url = environment.soMonitoringBackendURL + 'process-instance/' + processInstanceId;
+ return await (this.http.get<ProcessInstanceDetail>(url)
+ .pipe(
+ catchError(this.httpErrorHandlerService.handleError("GET", url))))
+ .toPromise();
+ }
+
+ // HTTP GET to return Process Definition using processDefinitionId
+ getProcessDefinition(processDefinitionId: string): Observable<Object> {
+ var url = environment.soMonitoringBackendURL + 'process-definition/' + processDefinitionId;
+ return this.http.get(url).pipe(
+ catchError(this.httpErrorHandlerService.handleError("GET", url))
+ );
+ }
+
+ // HTTP GET to return Variable Instance using ProcessInstanceID
+ getVariableInstance(processDefinitionId: string): Observable<Object> {
+ var url = environment.soMonitoringBackendURL + 'variable-instance/' + processDefinitionId;
+ return this.http.get(url).pipe(
+ catchError(this.httpErrorHandlerService.handleError("GET", url))
+ );
+ }
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.html b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.html
new file mode 100644
index 0000000..8ad955f
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.html
@@ -0,0 +1,112 @@
+<!--
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@est.tech, waqas.ikram@est.tech
+-->
+
+<div class="completeForm">
+ <div class="topCanvas">
+ <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 />
+ <mat-card-content>Process Instance Id: </mat-card-content>
+ <mat-card-content>{{ processInstanceID }}</mat-card-content>
+ <br />
+ <mat-card-content>Process Definition Id: </mat-card-content>
+ <mat-card-content>{{ processDefinitionID }}</mat-card-content>
+ <br />
+ <mat-card-content>Process Definition Name: </mat-card-content>
+ <mat-card-content>{{ processDefinitionName }}</mat-card-content>
+ </mat-card>
+ </div>
+ <br />
+
+ <div class="example-container mat-elevation-z8">
+ <mat-tab-group class="tab-group">
+ <mat-tab label="Activity Instances">
+ <mat-table [dataSource]="activityInstance">
+ <ng-container matColumnDef="activityId">
+ <mat-header-cell *matHeaderCellDef> Activity Id </mat-header-cell>
+ <mat-cell *matCellDef="let activity"> {{ activity.activityId }} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="activityName">
+ <mat-header-cell *matHeaderCellDef> Activity Name </mat-header-cell>
+ <mat-cell *matCellDef="let activity">
+ <div [ngSwitch]="!!activity.calledProcessInstanceId">
+ <div *ngSwitchCase="false"><a> {{ activity.activityName }} </a></div>
+ <div *ngSwitchCase="true"><a [routerLink]="['/details', activity.calledProcessInstanceId]"> {{ activity.activityName }} </a></div>
+ </div>
+ </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="activityType">
+ <mat-header-cell *matHeaderCellDef> Activity Type </mat-header-cell>
+ <mat-cell *matCellDef="let activity"> {{ activity.activityType }} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="startTime">
+ <mat-header-cell *matHeaderCellDef> Start Time </mat-header-cell>
+ <mat-cell *matCellDef="let activity"> {{ (activity.startTime | date:'yyyy-MM-dd HH:mm:sss Z') }} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="endTime">
+ <mat-header-cell *matHeaderCellDef> End Time </mat-header-cell>
+ <mat-cell *matCellDef="let activity"> {{ (activity.endTime | date:'yyyy-MM-dd HH:mm:sss Z') }} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="durationInMillis">
+ <mat-header-cell *matHeaderCellDef> Duration (ms) </mat-header-cell>
+ <mat-cell *matCellDef="let activity"> {{ activity.durationInMillis }} </mat-cell>
+ </ng-container>
+ <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
+ <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
+ </mat-table>
+ </mat-tab>
+
+ <mat-tab label="Variable Instances">
+ <mat-table [dataSource]="variableInstance">
+ <ng-container matColumnDef="name">
+ <mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
+ <mat-cell *matCellDef="let variable"> {{ variable.name }} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="type">
+ <mat-header-cell *matHeaderCellDef> Type </mat-header-cell>
+ <mat-cell *matCellDef="let variable"> {{ variable.type }} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="value">
+ <mat-header-cell *matHeaderCellDef> Value </mat-header-cell>
+ <mat-cell *matCellDef="let variable"> {{ variable.value }} </mat-cell>
+ </ng-container>
+ <mat-header-row *matHeaderRowDef="displayedColumnsVariable"></mat-header-row>
+ <mat-row *matRowDef="let row; columns: displayedColumnsVariable;"></mat-row>
+ </mat-table>
+ </mat-tab>
+ </mat-tab-group>
+ </div>
+</div>
+
+<ngx-spinner bdColor="rgba(51, 51, 51, 0.8)" size="large" color="#00285f" type="ball-spin-clockwise-fade-rotating"></ngx-spinner>
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.scss b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.scss
new file mode 100644
index 0000000..b96fe4a
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.scss
@@ -0,0 +1,88 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@est.tech, waqas.ikram@est.tech
+*/
+#canvas {
+ background: white;
+ padding: 0;
+ margin-left: -43px;
+ width: 70%;
+ height: 470px;
+ margin-top: 0;
+ 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: 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);
+ font-family: 'Montserrat', sans-serif;
+ font-size: 17px;
+}
+
+.topCanvas {
+ display: flex;
+ justify-content: space-between;
+}
+
+.mat-column-durationInMillis {
+ flex: 0 0 8%;
+}
+
+.mat-column-name {
+ flex: 0 0 40%;
+}
+
+.mat-column-type {
+ flex: 0 0 8%;
+}
+
+.mat-column-value {
+ flex: 0 0 52%;
+}
+
+.highlight:not(.djs-connection) .djs-visual > :nth-child(1) {
+ fill: cyan !important;
+ /* color elements as green */
+}
+
+.tab-group {
+ word-break: break-all;
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.spec.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.spec.ts
new file mode 100644
index 0000000..4ffacce
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.spec.ts
@@ -0,0 +1,218 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com, andrei.barcovschi@ericsson.com
+*/
+
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DetailsComponent } from './details.component';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+import { RouterTestingModule } from '@angular/router/testing';
+import { MatTableModule } from '@angular/material';
+import { inject } from '@angular/core/testing';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { HttpClientModule } from '@angular/common/http';
+import { HttpClient } from '@angular/common/http';
+import { RouterModule } from '@angular/router';
+import { APP_BASE_HREF } from '@angular/common';
+import { ToastrNotificationService } from '../toastr-notification-service.service';
+import { DataService } from '../data.service';
+import { Observable, of, throwError } from 'rxjs';
+import { ActivityInstance } from '../model/activityInstance.model';
+import { ProcessDefinitionDetail } from '../model/processDefinition.model';
+import { ProcessInstanceDetail } from '../model/processInstance.model';
+import { VariableInstance } from '../model/variableInstance.model';
+import { ActivatedRoute } from '@angular/router';
+import { Params } from '@angular/router';
+
+// Generate stub for toastr popup notifications
+class StubbedToastrNotificationService extends ToastrNotificationService {
+ toastrSettings() {}
+ info() {}
+ error() {}
+}
+
+const startActivity: ActivityInstance = {
+ activityId: "StartEvent_1",
+ processInstanceId: "processInstanceId-val-1234",
+ calledProcessInstanceId: "",
+ activityName: "",
+ activityType: "",
+ durationInMillis: "1",
+ endTime: "",
+ startTime: ""
+};
+
+const subProcessActivity: ActivityInstance = {
+ activityId: "CallActivity_14h26ae",
+ processInstanceId: "processInstanceId-val-1234",
+ calledProcessInstanceId: "1234",
+ activityName: "",
+ activityType: "",
+ durationInMillis: "1",
+ endTime: "",
+ startTime: ""
+};
+
+const processDefinition: ProcessDefinitionDetail = {
+ processDefinitionId: "processDefinitionId-val-1234",
+ processDefinitionXml: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+ "<bpmn:definitions xmlns:bpmn=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\" xmlns:di=\"http://www.omg.org/spec/DD/20100524/DI\" xmlns:dc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:camunda=\"http://camunda.org/schema/1.0/bpmn\" id=\"Definitions_01lwydo\" targetNamespace=\"http://bpmn.io/schema/bpmn\" exporter=\"Camunda Modeler\" exporterVersion=\"2.2.4\">" +
+ " <bpmn:process id=\"Process_1\" isExecutable=\"true\">" +
+ " <bpmn:startEvent id=\"StartEvent_1\">" +
+ " <bpmn:outgoing>SequenceFlow_1rrp6qt</bpmn:outgoing>" +
+ " </bpmn:startEvent>" +
+ " <bpmn:callActivity id=\"CallActivity_14h26ae\" name=\"Sub Process\" calledElement=\"DecomposeService\">" +
+ " <bpmn:incoming>SequenceFlow_1rrp6qt</bpmn:incoming>" +
+ " <bpmn:outgoing>SequenceFlow_0yvdjct</bpmn:outgoing>" +
+ " </bpmn:callActivity>" +
+ " <bpmn:sequenceFlow id=\"SequenceFlow_1rrp6qt\" sourceRef=\"StartEvent_1\" targetRef=\"CallActivity_14h26ae\" />" +
+ " <bpmn:endEvent id=\"EndEvent_039q5o1\">" +
+ " <bpmn:incoming>SequenceFlow_0yvdjct</bpmn:incoming>" +
+ " </bpmn:endEvent>" +
+ " <bpmn:sequenceFlow id=\"SequenceFlow_0yvdjct\" sourceRef=\"CallActivity_14h26ae\" targetRef=\"EndEvent_039q5o1\" />" +
+ " </bpmn:process>" +
+ " <bpmndi:BPMNDiagram id=\"BPMNDiagram_1\">" +
+ " <bpmndi:BPMNPlane id=\"BPMNPlane_1\" bpmnElement=\"Process_1\">" +
+ " <bpmndi:BPMNShape id=\"_BPMNShape_StartEvent_2\" bpmnElement=\"StartEvent_1\">" +
+ " <dc:Bounds x=\"173\" y=\"102\" width=\"36\" height=\"36\" />" +
+ " </bpmndi:BPMNShape>" +
+ " <bpmndi:BPMNShape id=\"CallActivity_14h26ae_di\" bpmnElement=\"CallActivity_14h26ae\">" +
+ " <dc:Bounds x=\"267\" y=\"80\" width=\"100\" height=\"80\" />" +
+ " </bpmndi:BPMNShape>" +
+ " <bpmndi:BPMNEdge id=\"SequenceFlow_1rrp6qt_di\" bpmnElement=\"SequenceFlow_1rrp6qt\">" +
+ " <di:waypoint x=\"209\" y=\"120\" />" +
+ " <di:waypoint x=\"267\" y=\"120\" />" +
+ " </bpmndi:BPMNEdge>" +
+ " <bpmndi:BPMNShape id=\"EndEvent_039q5o1_di\" bpmnElement=\"EndEvent_039q5o1\">" +
+ " <dc:Bounds x=\"451\" y=\"102\" width=\"36\" height=\"36\" />" +
+ " </bpmndi:BPMNShape>" +
+ " <bpmndi:BPMNEdge id=\"SequenceFlow_0yvdjct_di\" bpmnElement=\"SequenceFlow_0yvdjct\">" +
+ " <di:waypoint x=\"367\" y=\"120\" />" +
+ " <di:waypoint x=\"451\" y=\"120\" />" +
+ " </bpmndi:BPMNEdge>" +
+ " </bpmndi:BPMNPlane>" +
+ " </bpmndi:BPMNDiagram>" +
+ "</bpmn:definitions>"
+};
+
+const emptyProcessDefinition: ProcessDefinitionDetail = {
+ processDefinitionId: "processDefinitionId-val",
+ processDefinitionXml: ""
+};
+
+const processInstance: ProcessInstanceDetail = {
+ processInstanceId: "processInstanceId-val-1234",
+ processDefinitionId: "1",
+ processDefinitionName: "test",
+ superProcessInstanceId: "1"
+};
+
+const varInstanceObj: VariableInstance = {
+ name: 'ABC',
+ type: 'Object',
+ value: '{value: 1234}'
+};
+
+const varInstanceStr: VariableInstance = {
+ name: 'NameStr',
+ type: 'String',
+ value: 'valOfStr'
+};
+
+describe('DetailsComponent', (displayCamundaflow = {}) => {
+ // Create SPY Object for Jasmine tests to mock DataService
+ let spyDataService: jasmine.SpyObj<DataService>;
+ let component: DetailsComponent;
+ let fixture: ComponentFixture<DetailsComponent>;
+
+ beforeEach(async(() => {
+ spyDataService = jasmine.createSpyObj('DataService', ['getActivityInstance', 'getVariableInstance', 'getProcessDefinition', 'getProcessInstance']);
+
+ TestBed.configureTestingModule({
+ providers: [DetailsComponent, HttpClient, HttpTestingController,
+ { provide: APP_BASE_HREF, useValue: '/' },
+ { provide: ToastrNotificationService, useClass: StubbedToastrNotificationService },
+ { provide: DataService, useValue: spyDataService },
+ { provide: ActivatedRoute, useValue: { params: of({ id: '1234' }) } }],
+ imports: [RouterTestingModule, MatTableModule, HttpClientModule, RouterModule.forRoot([])],
+ declarations: [DetailsComponent],
+ schemas: [
+ CUSTOM_ELEMENTS_SCHEMA
+ ]
+ });
+ fixture = TestBed.createComponent(DetailsComponent);
+ component = fixture.componentInstance;
+ }));
+
+ // Ensure creation of DetailsComponent component
+ it('component should be created', inject([DetailsComponent],
+ (detailsComponent: DetailsComponent) => {
+ expect(detailsComponent).toBeTruthy();
+ }));
+
+ // Create a processInstance and ensure it is defined
+ it('processInstance should be defined if PII populated', async(() => {
+ spyDataService.getActivityInstance.and.returnValue(Promise.resolve([startActivity, subProcessActivity]));
+ spyDataService.getProcessDefinition.and.returnValue(of(processDefinition));
+ spyDataService.getProcessInstance.and.returnValue(Promise.resolve(processInstance));
+ spyDataService.getVariableInstance.and.returnValue(of([varInstanceObj]));
+ component.ngOnInit();
+
+ fixture.whenStable().then(() => {
+ expect(component.processInstance).toBeDefined();
+ });
+ }));
+
+ it('should handle bpmnViewer.importXML error', () => {
+ spyDataService.getActivityInstance.and.returnValue(Promise.resolve([startActivity, subProcessActivity]));
+ spyDataService.getProcessDefinition.and.returnValue(of(emptyProcessDefinition));
+ spyDataService.getProcessInstance.and.returnValue(Promise.resolve(processInstance));
+ spyDataService.getVariableInstance.and.returnValue(of([varInstanceObj]));
+ component.ngOnInit();
+ });
+
+ it('should handle error when dataService.getProcessInstance returns an error', () => {
+ spyDataService.getVariableInstance.and.returnValue(of([varInstanceObj]));
+ spyDataService.getProcessInstance.and.returnValue(Promise.reject(new Error('getProcessInstance Promise should not be resolved')));
+ component.ngOnInit();
+ });
+
+ it('should handle error when data.getVariableInstance returns an error', () => {
+ spyDataService.getActivityInstance.and.returnValue(Promise.resolve([startActivity, subProcessActivity]));
+ spyDataService.getProcessDefinition.and.returnValue(of(processDefinition));
+ spyDataService.getProcessInstance.and.returnValue(Promise.resolve(processInstance));
+ spyDataService.getVariableInstance.and.callFake(() => {
+ return throwError(new Error('getVariableInstance error'));
+ });
+ component.ngOnInit();
+ });
+
+ it('should handle error when data.getActivityInstance and data.getProcessDefinition return errors', () => {
+ spyDataService.getProcessInstance.and.returnValue(Promise.resolve(processInstance));
+ spyDataService.getVariableInstance.and.returnValue(of([varInstanceObj]));
+ spyDataService.getProcessDefinition.and.returnValue(of(processDefinition));
+ spyDataService.getActivityInstance.and.returnValue(Promise.reject(new Error('getActivityInstance Promise should not be resolved')));
+ spyDataService.getProcessDefinition.and.callFake(() => {
+ return throwError(new Error('getProcessDefinition error'));
+ });
+ component.ngOnInit();
+ });
+});
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.ts
new file mode 100644
index 0000000..a42fa3f
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/details/details.component.ts
@@ -0,0 +1,224 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@est.tech, waqas.ikram@est.tech
+*/
+
+import { Component, OnInit } from '@angular/core';
+import { DataService } from '../data.service';
+import { ActivatedRoute, Router } from "@angular/router";
+import { BpmnInfraRequest } from '../model/bpmnInfraRequest.model';
+import { ActivityInstance } from '../model/activityInstance.model';
+import { ProcessInstanceDetail } from '../model/processInstance.model';
+import { ProcessDefinitionDetail } from '../model/processDefinition.model';
+import { CommonModule } from '@angular/common';
+import Viewer from 'bpmn-js/lib/NavigatedViewer';
+import { ViewEncapsulation } from '@angular/core';
+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',
+ templateUrl: './details.component.html',
+ styleUrls: ['./details.component.scss'],
+ encapsulation: ViewEncapsulation.None
+})
+
+export class DetailsComponent implements OnInit {
+
+ @ViewChild("canvas") elementReference: ElementRef;
+
+ bpmnViewer: any;
+
+ processInstanceID: string;
+
+ processDefinitionID: string;
+
+ processDefinitionName: string;
+
+ activityInstance: ActivityInstance[];
+
+ processInstance: ProcessInstanceDetail;
+
+ processDefinition: ProcessDefinitionDetail;
+
+ variableInstance: VariableInstance[];
+
+ displayedColumns = ['activityId', 'activityName', 'activityType', 'startTime', 'endTime', 'durationInMillis'];
+
+ displayedColumnsVariable = ['name', 'type', 'value'];
+
+ constructor(private route: ActivatedRoute, private data: DataService, private popup: ToastrNotificationService,
+ private router: Router, private spinner: NgxSpinnerService) { }
+
+ async getActivityInstance(procInstId: string) {
+ await this.data.getActivityInstance(procInstId).then(
+ (data: ActivityInstance[]) => {
+ this.activityInstance = data;
+ console.log(data);
+ }, error => {
+ console.log(error);
+ this.popup.error("Unable to get activity instance details for id: " + procInstId + " Error code:" + error.status);
+ });
+ }
+
+ async getProcessDefinition(procDefId: string) {
+ await this.data.getProcessDefinition(procDefId).subscribe(
+ async (data: ProcessDefinitionDetail) => {
+ this.processDefinition = data;
+ console.log(data);
+ 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);
+ });
+ }
+
+ async getProcInstance(procInstId: string) {
+ await this.data.getProcessInstance(procInstId).then(
+ async (data: ProcessInstanceDetail) => {
+ this.processInstance = data;
+ this.processDefinitionID = this.processInstance.processDefinitionId;
+ this.processDefinitionName = this.processInstance.processDefinitionName;
+ console.log("Process definition id: " + this.processDefinitionID);
+ await this.getActivityInstance(this.processInstanceID);
+ await this.getProcessDefinition(this.processDefinitionID);
+ }, error => {
+ console.log(error);
+ this.popup.error("Unable to get process instance for id: " + procInstId + " Error code:" + error.status);
+ });
+ }
+
+ 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);
+ popup.error('Unable to load BPMN flow ');
+ spinner.hide();
+ } else {
+ spinner.hide();
+ let canvas = this.bpmnViewer.get('canvas');
+ var eventBus = this.bpmnViewer.get('eventBus');
+ var elementRegistry = this.bpmnViewer.get('elementRegistry');
+ var overlays = this.bpmnViewer.get('overlays');
+
+ 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', 'auto');
+ activities.forEach(a => {
+ canvas.addMarker(a.activityId, 'highlight');
+ });
+ }
+ });
+ }
+
+ 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[]) => {
+ this.variableInstance = [];
+ for (let i = 0; i < data.length; i++) {
+ var value = data[i]['value'];
+ var type = data[i]['type'];
+ if ((type == 'Object') && !(value == null)) {
+ try {
+ data[i]['value'] = JSON.stringify(value, null, 2);
+ }
+ catch (error) {
+ console.log("Unable to \nError Code: " + error);
+ }
+ }
+ this.variableInstance[i] = data[i];
+ }
+ console.log(data);
+ }, error => {
+ console.log(error);
+ this.popup.error("Unable to get Variable instances for id: " + procInstId + " Error code:" + error.status);
+ });
+ }
+
+ async ngOnInit() {
+ this.bpmnViewer = new Viewer({
+ container: '.canvas'
+ });
+ this.route.params.subscribe(
+ async params => {
+ this.processInstanceID = params.id as string;
+ console.log("Will GET BpmnInfraRequest instance using id: " + this.processInstanceID);
+ await this.getProcInstance(this.processInstanceID);
+
+ this.getVarInst(this.processInstanceID);
+ });
+ }
+
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.html b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.html
new file mode 100644
index 0000000..4fd8cc4
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.html
@@ -0,0 +1,205 @@
+<!--
+============LICENSE_START=======================================================
+Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com, andrei.barcovschi@ericsson.com
+-->
+
+<base href="/">
+
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+<link rel="stylesheet" ng-href="./home.component.scss">
+<div class="completeForm">
+ <div class="searchArea">
+
+ <!-- Dropdown Filter and TextBox for Service Instance Id -->
+ <div class="container-home">
+ <mat-form-field class="selectFilter">
+ <mat-select class="formatBox" [(value)]="searchData.selectedValueSII" placeholder="Select Filter">
+ <mat-option *ngFor="let option of options" [value]="option.value">{{option.name}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+ <mat-form-field class="valueInput">
+ <input matInput #searchValueSII type="text" [(ngModel)]="searchData.serviceInstanceId" placeholder="Service Instance Id">
+ </mat-form-field>
+ </div>
+
+ <!-- Dropdown Filter and TextBox for Request Id -->
+ <div class="container-home">
+ <mat-form-field class="selectFilter">
+ <mat-select class="formatBox" [(value)]="searchData.selectedValueRI" placeholder="Select Filter">
+ <mat-option *ngFor="let option of options" [value]="option.value">{{option.name}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+ <mat-form-field class="valueInput">
+ <input matInput #searchValueRI type="text" [(ngModel)]="searchData.requestId" placeholder="Request Id">
+ </mat-form-field>
+
+ <!-- Angular Start Date Picker -->
+ <mat-form-field class="startDate">
+ <input matInput #startDate [matDatepicker]="picker" [(ngModel)]="searchData.startDate" placeholder="Choose a start date">
+ <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
+ <mat-datepicker #picker></mat-datepicker>
+ </mat-form-field>
+
+ <!-- Dropdown box for Start Hour selection -->
+ <mat-form-field class="selectHour">
+ <mat-select class="formatBox" [(value)]="searchData.selectedStartHour" placeholder="Select Hour">
+ <mat-option *ngFor="let option of hourOptions" [value]="option">{{option}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+
+ <!-- Dropdown box for Start Minute selection -->
+ <mat-form-field class="selectMinute">
+ <mat-select class="formatBox" [(value)]="searchData.selectedStartMinute" placeholder="Select Minute">
+ <mat-option *ngFor="let option of minuteOptions" [value]="option">{{option}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+ </div>
+
+ <!-- Dropdown Filter and TextBox for Service Name -->
+ <div class="container-home">
+ <mat-form-field class="selectFilter">
+ <mat-select class="formatBox" [(value)]="searchData.selectedValueSN" placeholder="Select Filter">
+ <mat-option *ngFor="let option of options" [value]="option.value">{{option.name}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+ <mat-form-field class="valueInput">
+ <input matInput #searchValueSN type="text" [(ngModel)]="searchData.serviceInstanceName" placeholder="Service Name">
+ </mat-form-field>
+
+ <!-- Angular End Date Picker -->
+ <mat-form-field class="endDate">
+ <input matInput #endDate [matDatepicker]="endpicker" [(ngModel)]="searchData.endDate" placeholder="Choose an end date">
+ <mat-datepicker-toggle matSuffix [for]="endpicker"></mat-datepicker-toggle>
+ <mat-datepicker #endpicker></mat-datepicker>
+ </mat-form-field>
+
+ <!-- Dropdown box for End Hour selection -->
+ <mat-form-field class="selectHour">
+ <mat-select class="formatBox" [(value)]="searchData.selectedEndHour" placeholder="Select Hour">
+ <mat-option *ngFor="let option of hourOptions" [value]="option">{{option}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+
+ <!-- Dropdown box for End Minute selection -->
+ <mat-form-field class="selectMinute">
+ <mat-select class="formatBox" [(value)]="searchData.selectedEndMinute" placeholder="Select Minute">
+ <mat-option *ngFor="let option of minuteOptions" [value]="option">{{option}}</mat-option>
+ </mat-select>
+ </mat-form-field>
+ </div>
+
+ <!-- Dropdown Filter for Status -->
+ <div class="container-home">
+ <mat-form-field class="selectFilter">
+ <mat-select class="formatBox" [(value)]="searchData.selectedValueSTATUS" placeholder="Status">
+ <mat-option *ngFor="let statusOption of statusOptions" [value]="statusOption.value">{{ statusOption.name }}</mat-option>
+ </mat-select>
+ </mat-form-field>
+ </div>
+ <br />
+
+ <!-- Button to call makeCall() function to commence search based on parameters -->
+ <button (click)="makeCall()" class="fa fa-search"></button>
+ </div>
+
+ <br />
+
+ <!-- Table to display selected fields if data present -->
+ <div class="example-container mat-elevation-z8">
+ <mat-tab-group class="tab-group">
+ <mat-tab label="Service Instances">
+ <mat-table [dataSource]="processData" matSort>
+ <ng-container matColumnDef="requestId">
+ <mat-header-cell *matHeaderCellDef mat-sort-header> Request Id </mat-header-cell>
+ <mat-cell *matCellDef="let process"><a routerLink="" (click)="getProcessInstanceId(process.requestId)">{{ process.requestId }}</a></mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="serviceInstanceId">
+ <mat-header-cell *matHeaderCellDef mat-sort-header> Instance Id </mat-header-cell>
+ <mat-cell *matCellDef="let process"> {{ process.serviceInstanceId }} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="serviceInstanceName">
+ <mat-header-cell *matHeaderCellDef mat-sort-header> Instance Name </mat-header-cell>
+ <mat-cell *matCellDef="let process"> {{ process.serviceInstanceName }} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="networkId">
+ <mat-header-cell *matHeaderCellDef mat-sort-header> Network Id </mat-header-cell>
+ <mat-cell *matCellDef="let process"> {{ process.networkId }} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="requestStatus">
+ <mat-header-cell *matHeaderCellDef mat-sort-header> Request Status </mat-header-cell>
+ <mat-cell *matCellDef="let process"> {{ process.requestStatus }} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="serviceType">
+ <mat-header-cell *matHeaderCellDef mat-sort-header> Service Type </mat-header-cell>
+ <mat-cell *matCellDef="let process"> {{ process.serviceType }} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="startTime">
+ <mat-header-cell *matHeaderCellDef mat-sort-header> Start Time </mat-header-cell>
+ <mat-cell *matCellDef="let process"> {{ (process.startTime | date:'yyyy-MM-dd HH:mm:sss Z') }} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="endTime">
+ <mat-header-cell *matHeaderCellDef mat-sort-header> End Time </mat-header-cell>
+ <mat-cell *matCellDef="let process"> {{ (process.endTime | date:'yyyy-MM-dd HH:mm:sss Z') }} </mat-cell>
+ </ng-container>
+ <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
+ <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
+ </mat-table>
+ <mat-paginator [pageSizeOptions]="pageSizeOptions" showFirstLastButtons>
+ </mat-paginator>
+ </mat-tab>
+
+ <mat-tab label="Service Statistics">
+ <div id="servStats">
+ <table class="statsTable">
+ <tbody>
+ <tr>
+ <td>Total: {{ totalVal }}</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>Complete: {{ completeVal }}</td>
+ <td> {{ percentageComplete }}%</td>
+ </tr>
+ <tr>
+ <td>Failed: {{ failedVal }}</td>
+ <td> {{ percentageFailed }}%</td>
+ </tr>
+ <tr>
+ <td>In Progress: {{ inProgressVal }}</td>
+ <td> {{ percentageInProg }}%</td>
+ </tr>
+ <tr>
+ <td>Pending: {{ pendingVal }}</td>
+ <td> {{ percentagePending }}%</td>
+ </tr>
+ <tr>
+ <td>Unlocked: {{ unlockedVal }}</td>
+ <td> {{ percentageUnlocked }}%</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </mat-tab>
+ </mat-tab-group>
+ </div>
+</div>
+
+<ngx-spinner bdColor="rgba(51, 51, 51, 0.8)" size="large" color="#00285f" type="ball-spin-clockwise-fade-rotating"></ngx-spinner>
+<router-outlet></router-outlet>
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.scss b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.scss
new file mode 100644
index 0000000..9260e4c
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.scss
@@ -0,0 +1,130 @@
+/**
+============LICENSE_START=======================================================
+Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+@import "~@angular/material/prebuilt-themes/indigo-pink.css";
+
+.searchArea {
+ background-color: white;
+ padding: 10px;
+ height: 345px;
+ 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);
+}
+
+.mat-form-field-appearance-legacy .mat-form-field-wrapper {
+ padding-bottom: 1.25em;
+ font-family: 'Montserrat', sans-serif;
+}
+
+.selectFilter {
+ width: 120px;
+}
+
+.valueInput {
+ width: 400px;
+ margin-left: 30px;
+}
+
+.selectFilter.mat-select.ng-tns-c5-1.ng-star-inserted {
+ font-family: 'Montserrat', sans-serif;
+ font-size: 17px;
+}
+
+.mat-form-field-flex .valueInput {
+ font-family: 'Montserrat', sans-serif;
+ font-size: 17px;
+}
+
+.mat-primary .mat-option.mat-selected:not(.mat-option-disabled) {
+ color: #00285F;
+}
+
+.mat-option {
+ font-size: 17px;
+ line-height: 3em;
+ height: 3em;
+ font-family: 'Montserrat', sans-serif;
+}
+
+.mat-select-arrow {
+ color: #00285F;
+}
+
+.mat-form-field.mat-focused.mat-primary .mat-select-arrow {
+ color: #00285F;
+}
+
+.mat-form-field-appearance-legacy .mat-form-field-underline {
+ color: #00285F;
+}
+
+.fa {
+ float: left;
+ width: 120px;
+ padding: 10px;
+ background: #2196F3;
+ color: white;
+ height: 40px;
+ font-size: 17px;
+ border: 1px solid grey;
+ border-left: none;
+ cursor: pointer;
+}
+
+form.example button:hover {
+ background: #0b7dda;
+}
+
+form.example::after {
+ content: "";
+ clear: both;
+ display: table;
+}
+
+.formFields {
+ display: inline-flex;
+}
+
+.endDate,
+.startDate {
+ margin-left: 90px;
+ width: 140px;
+}
+
+.selectHour,
+.selectMinute {
+ margin-left: 30px;
+ width: 100px;
+}
+
+#servStats {
+ background-color: white;
+ padding: 10px;
+ font-size: 17px;
+ font-family: 'Montserrat', sans-serif;
+}
+
+.statsTable {
+ td {
+ padding: 12px 80px 12px 12px;
+ text-align: left;
+ border-bottom: 1px solid #ccc;
+ }
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.spec.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.spec.ts
new file mode 100644
index 0000000..0da24cc
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.spec.ts
@@ -0,0 +1,178 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com, andrei.barcovschi@ericsson.com
+*/
+
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HomeComponent } from './home.component';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+import { MatTableModule, MatNativeDateModule, MatTableDataSource, MatPaginatorModule } from '@angular/material';
+import { FormsModule } from '@angular/forms';
+import { MatDatepickerModule } from '@angular/material/datepicker';
+import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
+import { HttpClientModule } from '@angular/common/http';
+import { HttpClient } from '@angular/common/http';
+import { inject } from '@angular/core/testing';
+import { RouterModule } from '@angular/router';
+import { APP_BASE_HREF } from '@angular/common';
+import { ToastrNotificationService } from '../toastr-notification-service.service';
+import { environment } from '../../environments/environment.prod';
+import { Observable, of, throwError } from 'rxjs';
+import { SearchRequest } from '../model/SearchRequest.model';
+import { DataService } from '../data.service'; // may be able to remove
+import { BpmnInfraRequest } from '../model/bpmnInfraRequest.model';
+import { By } from '@angular/platform-browser';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { ProcessInstanceId } from '../model/processInstanceId.model';
+import { HttpResponse } from '@angular/common/http';
+import { Router } from '@angular/router';
+import { Routes } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+import { DetailsComponent } from '../details/details.component';
+
+// Generate stub for toastr popup notifications
+class StubbedToastrNotificationService extends ToastrNotificationService {
+ toastrSettings() {}
+ info() {}
+ error() {}
+}
+
+const routes: Routes = [ { path: 'details/114e9ae4-4a32-11e9-8646-d663bd873d93' , component: DetailsComponent} ]
+
+describe('HomeComponent', () => {
+ let spyDataService: jasmine.SpyObj<DataService>;
+ let router: Router;
+ let component: HomeComponent;
+ let fixture: ComponentFixture<HomeComponent>;
+
+ beforeEach(() => {
+ spyDataService = jasmine.createSpyObj('DataService', ['getBpmnInfraRequest', 'getProcessInstanceId']);
+
+ TestBed.configureTestingModule({
+ providers: [
+ { provide: DataService, useValue: spyDataService },
+ { provide: APP_BASE_HREF, useValue: '/' },
+ { provide: ToastrNotificationService, useClass: StubbedToastrNotificationService }],
+ imports: [MatPaginatorModule, BrowserAnimationsModule, MatTableModule, FormsModule, MatDatepickerModule, MatNativeDateModule, HttpClientModule, RouterTestingModule.withRoutes(routes)],
+ declarations: [HomeComponent, DetailsComponent],
+ schemas: [
+ CUSTOM_ELEMENTS_SCHEMA
+ ]
+ });
+
+ fixture = TestBed.createComponent(HomeComponent);
+ router = TestBed.get(Router);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ // Ensure creation of HomeComponent component
+ it('component should be created', () => {
+ expect(component).toBeTruthy();
+ });
+
+ // Ensure all statistic variables are initialised to zero
+ it('should ensure statistic variables are defaulted at zero', () => {
+ expect(component.totalVal === 0 && component.completeVal === 0 &&
+ component.inProgressVal === 0 && component.failedVal === 0 &&
+ component.pendingVal === 0 && component.unlockedVal === 0 &&
+ component.percentageComplete === 0 && component.percentageFailed === 0 &&
+ component.percentageInProg === 0 && component.percentagePending === 0 &&
+ component.percentageUnlocked === 0).toBeTruthy();
+ });
+
+ it('should should navigate to a process if response status is OK', async(() => {
+ spyDataService.getProcessInstanceId.and.returnValue(of(<HttpResponse<ProcessInstanceId>>{body: {processInstanceId: '114e9ae4-4a32-11e9-8646-d663bd873d93'}, status: 200}));
+ spyOn(router, 'navigate');
+ component.getProcessInstanceId('e8a75940-4a32-11e9-8646-d663bd873d93');
+
+ fixture.whenStable().then(() => {
+ expect(router.navigate).toHaveBeenCalledWith(['/details/114e9ae4-4a32-11e9-8646-d663bd873d93']);
+ });
+ }));
+
+ it('should handle error if no process instance id found', () => {
+ spyDataService.getProcessInstanceId.and.returnValue(of(<HttpResponse<ProcessInstanceId>>{body: {processInstanceId: 'getProcessInstanceId error not found'}, status: 404}));
+ component.getProcessInstanceId('e8a75940-4a32-11e9-8646-d663bd873d93');
+ });
+
+ it('should handle error when searchData.getSearchRequest returns an error', () => {
+ spyOn(component.searchData, 'getSearchRequest').and.callFake(() => {
+ return throwError(new Error('getSearchRequest error'));
+ });
+ component.makeCall();
+ });
+
+ it('should handle error when dataService.getBpmnInfraRequest returns an error', () => {
+ spyOn(component.searchData, 'getSearchRequest').and.returnValue(of(getSearchRequest("965d3c92-44e0-11e9-b210-d663bd873d93", "85a7c354-44e0-11e9-b210-d663bd873d93", undefined, undefined, undefined, undefined, undefined, undefined, "ALL")));
+ spyDataService.getBpmnInfraRequest.and.callFake(() => {
+ return throwError(new Error('getBpmnInfraRequest error'));
+ });
+ component.makeCall();
+ });
+
+ it('should calculate statistics correctly', async(() => {
+ let requestStatusTypes: string[] = ["COMPLETE", "IN_PROGRESS", "FAILED", "PENDING", "UNLOCKED"];
+ let processArr: BpmnInfraRequest[] = [];
+
+ // create 5 processes, one of each requestStatusType, with default time.
+ requestStatusTypes.forEach((status) => {
+ let serviceName = "service-" + status;
+ var process = getProcess("85a7c354-44e0-11e9-b210-d663bd873d93", "965d3c92-44e0-11e9-b210-d663bd873d93", serviceName, "048a6212-44e1-11e9-b210-d663bd873d93", status, "TestType", undefined, undefined);
+ processArr.push(process);
+ })
+
+ // search request has default filter.
+ spyOn(component.searchData, 'getSearchRequest').and.returnValue(of(getSearchRequest(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, "ALL")));
+ spyDataService.getBpmnInfraRequest.and.returnValue(of(processArr));
+ component.makeCall();
+
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+
+ expect(
+ component.totalVal === 5 && component.completeVal === 1 &&
+ component.inProgressVal === 1 && component.failedVal === 1 &&
+ component.pendingVal === 1 && component.unlockedVal === 1 &&
+ component.percentageComplete === 20 &&
+ component.percentageFailed === 20 &&
+ component.percentageInProg === 20 &&
+ component.percentagePending === 20 &&
+ component.percentageUnlocked === 20)
+ .toBeTruthy();
+ });
+ }));
+
+ function getSearchRequest(selectedValueSII = "EQ", serviceInstanceIdVal: string, selectedValueRI = "EQ", requestIdVal: string, selectedValueSN = "EQ", serviceInstanceNameVal: string, startTimeInMilliseconds = 0, endTimeInMilliseconds = 4, selectedValueSTATUS?: string): SearchRequest {
+ if (startTimeInMilliseconds > endTimeInMilliseconds) {
+ console.error("End time cannot be greater than start time.");
+ return undefined;
+ }
+ if (typeof selectedValueSTATUS === "string")
+ return new SearchRequest({ serviceInstanceId: [selectedValueSII, serviceInstanceIdVal], requestId: [selectedValueRI, requestIdVal], serviceInstanceName: [selectedValueSN, serviceInstanceNameVal], requestStatus: ["EQ", selectedValueSTATUS] }, startTimeInMilliseconds, endTimeInMilliseconds);
+ else
+ return new SearchRequest({ serviceInstanceId: [selectedValueSII, serviceInstanceIdVal], requestId: [selectedValueRI, requestIdVal], serviceInstanceName: [selectedValueSN, serviceInstanceNameVal] }, startTimeInMilliseconds, endTimeInMilliseconds);
+ }
+
+ function getProcess(requestIdVal: string, serviceInstanceIdVal: string, serviceInstanceNameVal: string, networkIdVal: string, requestStatusVal: string, serviceTypeVal: string, startTimeVal = "1", endTimeVal = "2"): BpmnInfraRequest {
+ return <BpmnInfraRequest>{ requestId: requestIdVal, serviceInstanceId: serviceInstanceIdVal, serviceInstanceName: serviceInstanceNameVal, networkId: networkIdVal, requestStatus: requestStatusVal, serviceType: serviceTypeVal, startTime: startTimeVal, endTime: endTimeVal };
+ }
+});
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.ts
new file mode 100644
index 0000000..01e6899
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.component.ts
@@ -0,0 +1,140 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com, andrei.barcovschi@ericsson.com
+*/
+
+import { Component, OnInit, ViewChild, ElementRef, Input, ViewEncapsulation } from '@angular/core';
+import { DataService } from '../data.service';
+import { ActivatedRoute, Router } from "@angular/router";
+import { BpmnInfraRequest } from '../model/bpmnInfraRequest.model';
+import { ProcessInstanceId } from '../model/processInstanceId.model';
+import { ToastrNotificationService } from '../toastr-notification-service.service';
+import { MatSelectModule } from '@angular/material/select';
+import { FormsModule, FormControl } from '@angular/forms';
+import { SearchData } from '../model/searchData.model';
+import { MatDatepickerModule } from '@angular/material/datepicker';
+import { SearchRequest } from '../model/SearchRequest.model';
+import { NgxSpinnerService } from 'ngx-spinner';
+import { MatFormFieldModule, MatInputModule, MatPaginator, MatSort, MatTableDataSource } from '@angular/material';
+import { Constants } from './home.constant';
+
+@Component({
+ selector: 'app-home',
+ templateUrl: './home.component.html',
+ styleUrls: ['./home.component.scss'],
+ encapsulation: ViewEncapsulation.None
+})
+
+export class HomeComponent {
+
+ totalVal = 0;
+ completeVal = 0;
+ inProgressVal = 0;
+ failedVal = 0;
+ pendingVal = 0;
+ unlockedVal = 0;
+ percentageComplete = 0;
+ percentageFailed = 0;
+ percentageInProg = 0;
+ percentagePending = 0;
+ percentageUnlocked = 0;
+
+ options = Constants.OPTIONS;
+ statusOptions = Constants.STATUS_OPTIONS;
+ hourOptions = Constants.HOUR_OPTIONS;
+ minuteOptions = Constants.MINUTE_OPTIONS;
+ displayedColumns = Constants.DISPLAYED_COLUMNS;
+ pageSizeOptions = Constants.DEFAULT_PAGE_SIZE_OPTIONS;
+
+ searchData: SearchData;
+ startingDate: Date;
+ processData: MatTableDataSource<BpmnInfraRequest>;
+
+ @ViewChild(MatPaginator) paginator: MatPaginator;
+ @ViewChild(MatSort) sort: MatSort;
+
+ constructor(private route: ActivatedRoute, private data: DataService,
+ private router: Router, private popup: ToastrNotificationService,
+ private spinner: NgxSpinnerService) {
+ this.searchData = new SearchData();
+ }
+
+ makeCall() {
+ this.spinner.show();
+
+ var search = this.searchData.getSearchRequest().subscribe((result: SearchRequest) => {
+
+ this.data.getBpmnInfraRequest(result.getFilters(), result.getStartTimeInMilliseconds(), result.getEndTimeInMilliseconds())
+ .subscribe((data: BpmnInfraRequest[]) => {
+ this.spinner.hide();
+ var processData: BpmnInfraRequest[] = data;
+ this.processData = new MatTableDataSource<BpmnInfraRequest>(processData);
+ this.processData.sort = this.sort;
+ this.processData.paginator = this.paginator;
+ this.processData.paginator.firstPage();
+
+ this.popup.info("Number of records found: " + data.length)
+
+ // Calculate Statistics for Service Statistics tab
+ this.completeVal = processData.filter(i => i.requestStatus === "COMPLETE").length;
+ this.inProgressVal = processData.filter(i => i.requestStatus === "IN_PROGRESS").length;
+ this.failedVal = processData.filter(i => i.requestStatus === "FAILED").length;
+ this.pendingVal = processData.filter(i => i.requestStatus === "PENDING").length;
+ this.unlockedVal = processData.filter(i => i.requestStatus === "UNLOCKED").length;
+ this.totalVal = processData.length;
+
+ // Calculate percentages to 2 decimal places and compare to 0 to avoid NaN error
+ if (this.totalVal != 0) {
+ this.percentageComplete = Math.round(((this.completeVal / this.totalVal) * 100) * 100) / 100;
+ this.percentageFailed = Math.round(((this.failedVal / this.totalVal) * 100) * 100) / 100;
+ this.percentageInProg = Math.round(((this.inProgressVal / this.totalVal) * 100) * 100) / 100;
+ this.percentagePending = Math.round(((this.pendingVal / this.totalVal) * 100) * 100) / 100;
+ this.percentageUnlocked = Math.round(((this.unlockedVal / this.totalVal) * 100) * 100) / 100;
+ }
+ console.log("COMPLETE: " + this.completeVal);
+ console.log("FAILED: " + this.failedVal);
+ }, error => {
+ console.log(error);
+ this.popup.error("Unable to perform search Error code:" + error.status);
+ this.spinner.hide();
+ });
+ }, error => {
+ console.log("Data validation error " + error);
+ this.popup.error(error);
+ this.spinner.hide();
+ });
+ }
+
+ getProcessInstanceId(requestId: string) {
+ this.spinner.show();
+
+ var response = this.data.getProcessInstanceId(requestId).subscribe((data) => {
+ if (data.status == 200) {
+ this.spinner.hide();
+ var processInstanceId = (data.body as ProcessInstanceId).processInstanceId;
+ this.router.navigate(['/details/' + processInstanceId]);
+ } else {
+ this.popup.error('No process instance id found: ' + requestId);
+ this.spinner.hide();
+ console.log('No process instance id found: ' + requestId);
+ }
+ });
+ }
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.constant.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.constant.ts
new file mode 100644
index 0000000..72c98af
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/home/home.constant.ts
@@ -0,0 +1,41 @@
+
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2019 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: andrei.barcovschi@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+export class Constants {
+ public static OPTIONS = [{ name: "EQUAL", value: "EQ" }, { name: "NOT EQUAL", value: "NEQ" }, { name: "LIKE", value: "LIKE" }];
+
+ public static STATUS_OPTIONS = [{ name: "ALL", value: "ALL" }, { name: "COMPLETE", value: "COMPLETE" }, { name: "IN_PROGRESS", value: "IN_PROGRESS" },
+ { name: "FAILED", value: "FAILED" }, { name: "PENDING", value: "PENDING" }, { name: "UNLOCKED", value: "UNLOCKED" }];
+
+ public static HOUR_OPTIONS = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11",
+ "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"];
+
+ public static MINUTE_OPTIONS = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15",
+ "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35",
+ "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55",
+ "56", "57", "58", "59"];
+
+ public static DISPLAYED_COLUMNS = ['requestId', 'serviceInstanceId', 'serviceInstanceName', 'networkId', 'requestStatus', 'serviceType', 'startTime', 'endTime'];
+
+ public static DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/http-error-handler.service.spec.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/http-error-handler.service.spec.ts
new file mode 100644
index 0000000..9082641
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/http-error-handler.service.spec.ts
@@ -0,0 +1,44 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { TestBed, inject } from '@angular/core/testing';
+
+import { HttpErrorHandlerService } from './http-error-handler.service';
+import { ToastrNotificationService } from './toastr-notification-service.service';
+
+class StubbedToastrNotificationService extends ToastrNotificationService {
+ toastrSettings() {
+ }
+}
+
+describe('HttpErrorHandlerService', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers: [HttpErrorHandlerService,
+ { provide: ToastrNotificationService, useClass: StubbedToastrNotificationService }],
+ });
+ });
+
+ it('ErrorHandler should be created', inject([HttpErrorHandlerService], (service: HttpErrorHandlerService) => {
+ expect(service).toBeTruthy();
+ }));
+});
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/http-error-handler.service.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/http-error-handler.service.ts
new file mode 100644
index 0000000..33f4812
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/http-error-handler.service.ts
@@ -0,0 +1,53 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@est.tech, waqas.ikram@est.tech
+*/
+
+import { Injectable } from '@angular/core';
+import { ToastrNotificationService } from './toastr-notification-service.service';
+import { HttpErrorResponse } from '@angular/common/http';
+import { Observable, of, throwError } from 'rxjs';
+
+@Injectable({
+ providedIn: 'root'
+})
+/** Handles HttpClient errors */
+export class HttpErrorHandlerService {
+
+ constructor(private popup: ToastrNotificationService) { }
+
+ handleError(operation = 'operation', url = 'url') {
+ return (error: HttpErrorResponse) => {
+ if (error.error instanceof ErrorEvent) {
+ console.error('An error occurred:', error.error.message);
+ this.popup.error("An error occurred for operation: " + operation + " using url: " + url + " Detail: " + error.error.message);
+ return throwError("An error occurred for operation: " + operation);
+ }
+ if (error.status == 500 || error.status == 0) {
+ this.popup.error("Internal Service Error occured for operation: " + operation + " please check backend service log. status code: " + error.status);
+ }
+ console.error(
+ 'Backend returned status code: ', error.status + ' from URL ' + url);
+ return throwError(error.error || "Internal Service Error occured for operation: " +
+ operation + ". Please check backend service log. Status code: " + error.status);
+ };
+
+ }
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/SearchRequest.model.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/SearchRequest.model.ts
new file mode 100644
index 0000000..9f0606c
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/SearchRequest.model.ts
@@ -0,0 +1,42 @@
+
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+export class SearchRequest {
+
+ constructor(private filter: {}, private startTimeInMilliseconds: number, private endTimeInMilliseconds: number) {
+
+ }
+
+
+ public getFilters(): {} {
+ return this.filter;
+ }
+
+ public getStartTimeInMilliseconds(): number {
+ return this.startTimeInMilliseconds;
+ }
+
+ public getEndTimeInMilliseconds(): number {
+ return this.endTimeInMilliseconds;
+ }
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/activityInstance.model.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/activityInstance.model.ts
new file mode 100644
index 0000000..86831f2
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/activityInstance.model.ts
@@ -0,0 +1,32 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+export interface ActivityInstance {
+ activityId: string;
+ activityName: string;
+ activityType: string;
+ processInstanceId: string;
+ calledProcessInstanceId: string;
+ startTime: string;
+ endTime: string;
+ durationInMillis: string;
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/bpmnInfraRequest.model.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/bpmnInfraRequest.model.ts
new file mode 100644
index 0000000..e25b06f
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/bpmnInfraRequest.model.ts
@@ -0,0 +1,32 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+export interface BpmnInfraRequest {
+ requestId: string;
+ serviceInstanceId: string;
+ serviceInstanceName: string;
+ networkId: string;
+ requestStatus: string;
+ serviceType: string;
+ startTime: string;
+ endTime: string;
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/processDefinition.model.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/processDefinition.model.ts
new file mode 100644
index 0000000..c9ce7fe
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/processDefinition.model.ts
@@ -0,0 +1,26 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+export interface ProcessDefinitionDetail {
+ processDefinitionId: string;
+ processDefinitionXml: string;
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/processInstance.model.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/processInstance.model.ts
new file mode 100644
index 0000000..2187436
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/processInstance.model.ts
@@ -0,0 +1,28 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+export interface ProcessInstanceDetail {
+ processInstanceId: string;
+ processDefinitionId: string;
+ processDefinitionName: string;
+ superProcessInstanceId: string;
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/processInstanceId.model.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/processInstanceId.model.ts
new file mode 100644
index 0000000..6acf4be
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/processInstanceId.model.ts
@@ -0,0 +1,25 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+export interface ProcessInstanceId {
+ processInstanceId: string;
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/searchData.model.spec.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/searchData.model.spec.ts
new file mode 100644
index 0000000..5323cce
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/searchData.model.spec.ts
@@ -0,0 +1,78 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: andrei.barcovschi@ericsson.com
+*/
+
+import { SearchData } from './searchData.model';
+import { SearchRequest } from './SearchRequest.model';
+import { Observable, throwError } from 'rxjs';
+
+describe('SearchData', () => {
+ let searchRequest: SearchRequest;
+ let searchData: SearchData;
+
+ beforeEach(() => {
+ searchData = new SearchData();
+ });
+
+ it('should return a SearchRequest observable with selectedValueSTATUS != ALL', () => { // NOT ALL CHANGE TEST TO TEST THIS ISNTESASD
+ searchData.serviceInstanceId = "bd827d8c-4b07-11e9-8646-d663bd873d93";
+ searchData.requestId = "cf1343d8-4b07-11e9-8646-d663bd873d93";
+ searchData.serviceInstanceName = "service-123";
+ searchData.selectedValueSTATUS = "COMPLETE";
+
+ searchData.getSearchRequest().subscribe((request: SearchRequest) => {
+ searchRequest = request;
+ });
+ let filters = searchRequest.getFilters();
+ expect(searchRequest.getFilters()).toEqual({ serviceInstanceId: [ 'EQ', 'bd827d8c-4b07-11e9-8646-d663bd873d93' ],
+ requestId: [ 'EQ', 'cf1343d8-4b07-11e9-8646-d663bd873d93' ],
+ serviceInstanceName: [ 'EQ', 'service-123' ],
+ requestStatus: [ 'EQ', 'COMPLETE' ]
+ });
+ expect(searchRequest.getStartTimeInMilliseconds()).toBe(searchData.startDate.getTime());
+ expect(searchRequest.getEndTimeInMilliseconds()).toBe(searchData.endDate.getTime());
+ });
+
+ it('should throw an error if found incorrect start or end date', () => {
+ searchData.startDate = null;
+ searchData.endDate = undefined;
+ searchData.getSearchRequest().subscribe({
+ error: (err) => {
+ expect(err).toEqual('Found end or start date empty, Please enter start and end date')
+ }
+ });
+ });
+
+ it('should throw an error if startTimeInMilliseconds > endTimeInMilliseconds', () => {
+ searchData.startDate = new Date('March 20, 2019 02:00:00');
+ searchData.endDate = new Date('March 20, 2019 01:00:00');
+ searchData.selectedStartHour = '02';
+ searchData.selectedEndHour = '01';
+ searchData.selectedStartMinute = '00';
+ searchData.selectedEndMinute = '00';
+
+ searchData.getSearchRequest().subscribe({
+ error: (err) => {
+ expect(err).toEqual("End time: " + searchData.endDate + " can not be greater then start time: " + searchData.startDate)
+ }
+ });
+ });
+});
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/searchData.model.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/searchData.model.ts
new file mode 100644
index 0000000..a948eb7
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/searchData.model.ts
@@ -0,0 +1,107 @@
+import { ToastrNotificationService } from "../toastr-notification-service.service";
+
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { Observable, throwError, of } from 'rxjs';
+import { SearchRequest } from "./SearchRequest.model";
+import { Input } from "@angular/core";
+
+export class SearchData {
+
+ @Input() selectedValueSII = "EQ";
+ @Input() selectedValueRI = "EQ";
+ @Input() selectedValueSN = "EQ";
+ @Input() selectedValueSTATUS = "ALL";
+
+ private now = Date.now();
+ // Minus 1 hour from current time for start date
+ @Input() startDate = new Date(this.now - (1 * 60 * 60 * 1000));
+ @Input() selectedStartHour = this.getNumberAsString(this.startDate.getHours());
+ @Input() selectedStartMinute = this.getNumberAsString(this.startDate.getMinutes());
+
+ @Input() endDate = new Date(this.now);
+ @Input() selectedEndHour = this.getNumberAsString(this.endDate.getHours());
+ @Input() selectedEndMinute = this.getNumberAsString(this.endDate.getMinutes());
+
+
+ @Input() serviceInstanceId: string;
+ @Input() requestId: string;
+ @Input() serviceInstanceName: string;
+
+ private startTimeInMilliseconds: number;
+ private endTimeInMilliseconds: number;
+
+ constructor() {
+ }
+
+ public getSearchRequest(): Observable<SearchRequest> {
+ var searchFields = {};
+ if ((!this.startDate || this.startDate === null) || (!this.endDate || this.endDate === null)) {
+ console.error("Found either start time or end time null or undefined");
+ return throwError("Found end or start date empty, Please enter start and end date");
+ }
+
+ this.startDate.setHours(parseInt(this.selectedStartHour));
+ this.startDate.setMinutes(parseInt(this.selectedStartMinute));
+
+ this.endDate.setHours(parseInt(this.selectedEndHour));
+ this.endDate.setMinutes(parseInt(this.selectedEndMinute));
+
+ this.startTimeInMilliseconds = this.startDate.getTime();
+ this.endTimeInMilliseconds = this.endDate.getTime();
+
+ if (this.startTimeInMilliseconds > this.endTimeInMilliseconds) {
+ console.error("End time: " + this.endDate + " can not be greater then start time: " + this.startDate);
+ return throwError("End time: " + this.endDate + " can not be greater then start time: " + this.startDate);
+ }
+
+
+ if (!this.isEmpty(this.selectedValueSII) && !this.isEmpty(this.serviceInstanceId)) {
+ searchFields["serviceInstanceId"] = [this.selectedValueSII, this.serviceInstanceId]
+ }
+ if (!this.isEmpty(this.selectedValueRI) && !this.isEmpty(this.requestId)) {
+ searchFields["requestId"] = [this.selectedValueRI, this.requestId]
+ }
+ if (!this.isEmpty(this.selectedValueSN) && !this.isEmpty(this.serviceInstanceName)) {
+ searchFields["serviceInstanceName"] = [this.selectedValueSN, this.serviceInstanceName]
+ }
+
+ if (!this.isEmpty(this.selectedValueSTATUS) && this.selectedValueSTATUS !== "ALL") {
+ searchFields["requestStatus"] = ["EQ", this.selectedValueSTATUS]
+ }
+
+ return of(new SearchRequest(searchFields, this.startTimeInMilliseconds, this.endTimeInMilliseconds));
+ }
+
+ private isEmpty(str) {
+ return (!str || 0 === str.length);
+ }
+
+ private getNumberAsString(num: number) {
+ if (num <= 9) {
+ return "0" + num;
+ }
+ return "" + num;
+ }
+
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/variableInstance.model.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/variableInstance.model.ts
new file mode 100644
index 0000000..a4a3a35
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/model/variableInstance.model.ts
@@ -0,0 +1,27 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+export interface VariableInstance {
+ name: string;
+ value: string;
+ type: string;
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.html b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.html
new file mode 100644
index 0000000..4b8edbe
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.html
@@ -0,0 +1,29 @@
+<!--
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+-->
+
+<nav>
+ <ul>
+ <li>
+ <a routerLink="/">Home</a>
+ </li>
+ </ul>
+</nav>
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.scss b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.scss
new file mode 100644
index 0000000..dbc408f
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.scss
@@ -0,0 +1,44 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+nav {
+ background: #00285F;
+ height: 100%;
+ width: 90px;
+
+ ul {
+ list-style-type: none;
+ padding: 0;
+ margin: 0;
+
+ li {
+ a {
+ color: #fff;
+ padding: 20px;
+ display: block;
+ }
+
+ .activated {
+ background-color: #00a8ff;
+ }
+ }
+ }
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.spec.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.spec.ts
new file mode 100644
index 0000000..b7bcd0d
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.spec.ts
@@ -0,0 +1,61 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SidebarComponent } from './sidebar.component';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+import { HttpClientModule } from '@angular/common/http';
+import { HttpTestingController } from '@angular/common/http/testing';
+import { HttpClient } from '@angular/common/http';
+import { inject } from '@angular/core/testing';
+import { RouterModule } from '@angular/router';
+import { APP_BASE_HREF } from '@angular/common';
+
+describe('SidebarComponent', () => {
+ let component: SidebarComponent;
+ let fixture: ComponentFixture<SidebarComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ providers: [SidebarComponent, HttpClient, HttpTestingController, { provide: APP_BASE_HREF, useValue: '/' }],
+ imports: [HttpClientModule, RouterModule.forRoot([])],
+ declarations: [SidebarComponent],
+ schemas: [
+ CUSTOM_ELEMENTS_SCHEMA
+ ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SidebarComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('component should be created', async(inject([HttpTestingController, SidebarComponent],
+ (httpClient: HttpTestingController, sideComponent: SidebarComponent) => {
+ expect(sideComponent).toBeTruthy();
+ })));
+
+});
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.ts
new file mode 100644
index 0000000..e032bab
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/sidebar/sidebar.component.ts
@@ -0,0 +1,39 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { Component, OnInit } from '@angular/core';
+import { Router, NavigationEnd } from '@angular/router';
+
+@Component({
+ selector: 'app-sidebar',
+ templateUrl: './sidebar.component.html',
+ styleUrls: ['./sidebar.component.scss']
+})
+
+export class SidebarComponent {
+
+ currentUrl: string;
+
+ constructor(private router: Router) {
+ router.events.subscribe((_: NavigationEnd) => this.currentUrl = _.url);
+ }
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/ssl/localhost.crt b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/ssl/localhost.crt
new file mode 100644
index 0000000..7995c0e
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/ssl/localhost.crt
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID5jCCAs6gAwIBAgIUPVNQnCGr+uu048oN/oILqbk+DKwwDQYJKoZIhvcNAQEL
+BQAwgZ8xCzAJBgNVBAYTAkdCMQ8wDQYDVQQIDAZMb25kb24xDzANBgNVBAcMBkxv
+bmRvbjEYMBYGA1UECgwPTXkgT3JnYW5pc2F0aW9uMR8wHQYDVQQLDBZNeSBPcmdh
+bmlzYXRpb25hbCBVbml0MR8wHQYJKoZIhvcNAQkBFhBlbWFpbEBkb21haW4uY29t
+MRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjAwODA3MTIyMjM2WhcNMzAwNTA3MTIy
+MjM2WjCBnzELMAkGA1UEBhMCR0IxDzANBgNVBAgMBkxvbmRvbjEPMA0GA1UEBwwG
+TG9uZG9uMRgwFgYDVQQKDA9NeSBPcmdhbmlzYXRpb24xHzAdBgNVBAsMFk15IE9y
+Z2FuaXNhdGlvbmFsIFVuaXQxHzAdBgkqhkiG9w0BCQEWEGVtYWlsQGRvbWFpbi5j
+b20xEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAKCtMRhrl1o1obijVfREsIatq/fEiFETCtSx3mJVKjZjYNHFn2/OjvXo
+ncABnhKiFND8XiLYEgzDw9rtX3l2RVe9gQm2zNUvKPcmO+D4Dsn6QJu8HS7uDU8m
+gaXRiEUHsjD+jvEF/sUKjD565XRGd9qCyDpdtjra2W7CGZdzTrdepMRJhxMmA0fB
+t3JsV/52WMCqU6drSxT8hH7PvXh4nwr9DQ2fvUZarRptiW2Dg9zSqO+6M3XWCvUI
+jdm4Q0jxXY2jCLsh1oTo3dIYdHedB4LORXAPIRsLdJ1/ofl9NdyL20kG4ONIdJXv
+5mTuPGBATGOWEJvD8TTxrZtEMx9GNTsCAwEAAaMYMBYwFAYDVR0RBA0wC4IJbG9j
+YWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQAIDUoitU/11f9ApfPXwtuDaPeX20sc
+gSfq/MLQ9LttSi/SpAjebSlp12JNkZvxuV+2cPmc92NWv8WXqfyP+0BDhlGTm1qp
+Hc/wRB9ASG/7Z1imAh+zpNXFe0fV0HpUqJx33ywiXLoMTTaSvwPSF4VEki8g9h2R
+8zVXjsaE0ybi4eUIKG+ZJ2EBaVgLMEm+osVMnkTEWIeR3XN66Ko2SegvOrAjfOyz
+CIqkDvPhowYkKVV4LSsFIgz+YKOVMxaEcHbrxciYKymmWQ/9I/ek8TUs8C4z6cKs
+n+9nvYisfFpZ6tpMU+cgYkGezOCV5+nAri+SHoAfAOMXVPLACT39sOF9
+-----END CERTIFICATE-----
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/ssl/localhost.key b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/ssl/localhost.key
new file mode 100644
index 0000000..85e6b7e
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/ssl/localhost.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCgrTEYa5daNaG4
+o1X0RLCGrav3xIhREwrUsd5iVSo2Y2DRxZ9vzo716J3AAZ4SohTQ/F4i2BIMw8Pa
+7V95dkVXvYEJtszVLyj3Jjvg+A7J+kCbvB0u7g1PJoGl0YhFB7Iw/o7xBf7FCow+
+euV0Rnfagsg6XbY62tluwhmXc063XqTESYcTJgNHwbdybFf+dljAqlOna0sU/IR+
+z714eJ8K/Q0Nn71GWq0abYltg4Pc0qjvujN11gr1CI3ZuENI8V2Nowi7IdaE6N3S
+GHR3nQeCzkVwDyEbC3Sdf6H5fTXci9tJBuDjSHSV7+Zk7jxgQExjlhCbw/E08a2b
+RDMfRjU7AgMBAAECggEAByszAY/rVM8HxCEleJyH87pT7d4K5vMejJbTATgjhgGx
+FCrpDif9IOOcBjEMSHCK1TgtSwiw5XjmiCIHHHg2Z8/ArhpF0U0lWsGN8l+e6UwN
+DeW6t5lPZrSlHCzZE5tgS+dPoVlPIKNz1mXNTv7F4i3rmQ8NTlrtUI/AbI1seanh
+Ofb2yhHkkiHYIUridCDTuhk9hMmypHB9THA7SFRB7C9/zO8T95I2D1QQ5ZO5xKGg
+rDAMacSeQMnuKNcyuF4RYoh0T4PmM1NFGH1F1+QKTAt5CU0rkZtMHZ9YuYPYCC1S
+f1YrPQSJ5mFstaF9kWDp1rnR2J8Od/KU5ZSOgmvMoQKBgQDUithsDxnGEOQCKXfX
+e6/kgaL7mB5Q/Pgeyiy5lyBjTLZcbFeaDzkRBR3zL5v8xbNZ4IsJqkaxJavrIwr4
+R2+WvuznEaeLhFds0ze57kDyV/uunsQwBSJSXYohCRiq1gc7nqpamSSpFFI9Ls81
+JmXSPdyosRWESjCTCrQffZFKhQKBgQDBh4VZ9lSAGfASKjkqGLncAEHcnCbavQoy
+2DlHEhA+gZDvR2CSsunIxlQerZC78KcTA+oex54Ovi+NG8Rx6qyyywxiGjm0e1yG
+B2z060CTO9PlMhs81kXJkUDxR4tHyMNtLaFKICJ9J6wZXBnYZcMU+Do7OhlRVoaL
+qrNwhonsvwKBgCCTq3pckim+mwQN0RWRGrOefxmrBjKJo4osmNBVbpxpvKXL4V12
+qduG+kE08ea7crL67LStiapLSN+AfoTxhhQH7Y25MgH7Zd8DPM5dy0yZ2bS5Fv75
+Onp/ZdWMbGB6757eweOjB3B28ef4zb+qw/6GhtTAV7jwGiPfhx4wg911AoGBAIAP
+1H82UK4/+6uZgyBHIl3hUbPRJKjkJOaGTEiqPFOQWz7rJY2NlMQF8U4nnjmvQm+D
+zJ23i/DHiyG9+R1EpCjf0f7sybiTVSNfsIrVTXLgSRRGNt3oEGAUnTvMEu9ae284
+nZ02bHwTD3/sgTHADPpIVAgzJuO69Odg+sKAVK5zAoGAVn6bUm+QVuELmn8CNT+y
+XsSks5gu0MDwuSbUwjuNjSGMEab2lwyIgY8CduopyJWLPgkVtALiuXxp6OzPNCE4
+pC/5HNaqawCQ7Kgbk6MjRwY551HQRgMG7wf9iFBP8sfdWG30vYFmiYWN4oUEDi5j
+ytwU+extcKSRxj/O1op3KDI=
+-----END PRIVATE KEY-----
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/toastr-notification-service.service.spec.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/toastr-notification-service.service.spec.ts
new file mode 100644
index 0000000..cf96749
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/toastr-notification-service.service.spec.ts
@@ -0,0 +1,43 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { TestBed, inject } from '@angular/core/testing';
+
+import { ToastrNotificationService } from './toastr-notification-service.service';
+
+class StubbedToastrNotificationService extends ToastrNotificationService {
+ toastrSettings() {
+ }
+}
+
+describe('ToastrNotificationService', () => {
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers: [ToastrNotificationService,
+ { provide: ToastrNotificationService, useClass: StubbedToastrNotificationService }]
+ });
+ });
+
+ it('component should be created', inject([ToastrNotificationService], (service: ToastrNotificationService) => {
+ expect(service).toBeTruthy();
+ }));
+});
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/toastr-notification-service.service.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/toastr-notification-service.service.ts
new file mode 100644
index 0000000..43b8f6f
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/toastr-notification-service.service.ts
@@ -0,0 +1,59 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { Injectable } from '@angular/core';
+declare var toastr: any
+@Injectable({
+ providedIn: 'root'
+})
+export class ToastrNotificationService {
+
+ constructor() { this.toastrSettings() }
+
+ error(message: string) {
+ toastr.error(message, "Error");
+ }
+
+ info(message: string) {
+ toastr.info(message, "Info");
+ }
+
+ toastrSettings() {
+ toastr.options = {
+ "closeButton": false,
+ "debug": false,
+ "newestOnTop": false,
+ "progressBar": false,
+ "positionClass": "toast-bottom-full-width",
+ "preventDuplicates": true,
+ "onclick": null,
+ "showDuration": "300",
+ "hideDuration": "1000",
+ "timeOut": "5000",
+ "extendedTimeOut": "1000",
+ "showEasing": "swing",
+ "hideEasing": "linear",
+ "showMethod": "fadeIn",
+ "hideMethod": "fadeOut"
+ }
+ }
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.html b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.html
new file mode 100644
index 0000000..4862f3f
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.html
@@ -0,0 +1,25 @@
+<!--
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+-->
+
+<nav>
+ <h1><a class="navbar-brand">SO Monitoring</a></h1>
+</nav>
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.scss b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.scss
new file mode 100644
index 0000000..d33c899
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.scss
@@ -0,0 +1,59 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+.navbar-brand {
+ display: inline;
+ margin-right: 1rem;
+ font-size: 1.25rem;
+ line-height: inherit;
+ white-space: nowrap;
+}
+
+nav {
+ background: #00285F;
+ height: 40px;
+
+ ul {
+ list-style-type: none;
+ padding: 0;
+ margin: 0;
+
+ li {
+ a {
+ color: #fff;
+ padding: 20px;
+ display: block;
+ }
+
+ .activated {
+ background-color: #00a8ff;
+ }
+ }
+ }
+}
+
+h1 {
+ color: white;
+ text-indent: 90px;
+ padding-top: 0;
+ padding-bottom: 10px;
+ font-size: 1.9rem;
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.spec.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.spec.ts
new file mode 100644
index 0000000..bd94bba
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.spec.ts
@@ -0,0 +1,51 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TopbarComponent } from './topbar.component';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+
+describe('TopbarComponent', () => {
+ let component: TopbarComponent;
+ let fixture: ComponentFixture<TopbarComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [TopbarComponent],
+ schemas: [
+ CUSTOM_ELEMENTS_SCHEMA
+ ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(TopbarComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('component should be created', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.ts
new file mode 100644
index 0000000..2e6c908
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/app/topbar/topbar.component.ts
@@ -0,0 +1,35 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-topbar',
+ templateUrl: './topbar.component.html',
+ styleUrls: ['./topbar.component.scss']
+})
+
+export class TopbarComponent {
+
+ constructor() { }
+
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/assets/.gitkeep b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/assets/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/assets/.gitkeep
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/browserslist b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/browserslist
new file mode 100644
index 0000000..8e09ab4
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/browserslist
@@ -0,0 +1,9 @@
+# This file is currently used by autoprefixer to adjust CSS to support the below specified browsers
+# For additional information regarding the format and rule options, please see:
+# https://github.com/browserslist/browserslist#queries
+# For IE 9-11 support, please uncomment the last line of the file and adjust as needed
+> 0.5%
+last 2 versions
+Firefox ESR
+not dead
+# IE 9-11 \ No newline at end of file
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/environments/environment.prod.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/environments/environment.prod.ts
new file mode 100644
index 0000000..3612073
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/environments/environment.prod.ts
@@ -0,0 +1,3 @@
+export const environment = {
+ production: true
+};
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/environments/environment.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/environments/environment.ts
new file mode 100644
index 0000000..bf2f31d
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/environments/environment.ts
@@ -0,0 +1,28 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+
+export const environment = {
+ production: false,
+
+ soMonitoringBackendURL: 'https://so-monitoring:30224/so/monitoring/'
+};
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/favicon.png b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/favicon.png
new file mode 100644
index 0000000..2cdb98f
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/favicon.png
Binary files differ
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/index.html b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/index.html
new file mode 100644
index 0000000..5895c6e
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/index.html
@@ -0,0 +1,42 @@
+<!--
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+-->
+
+<!doctype html>
+<html lang="en">
+
+<head>
+ <meta charset="utf-8">
+ <title>SO Monitor</title>
+ <base href="/">
+
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <link rel="icon" type="image/x-icon" href="favicon.png">
+ <link href="https://fonts.googleapis.com/css?family=Montserrat:300,700" rel="stylesheet">
+ <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
+
+</head>
+
+<body>
+ <app-root></app-root>
+</body>
+
+</html>
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/karma.conf.js b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/karma.conf.js
new file mode 100644
index 0000000..b6e0042
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/karma.conf.js
@@ -0,0 +1,31 @@
+// Karma configuration file, see link for more information
+// https://karma-runner.github.io/1.0/config/configuration-file.html
+
+module.exports = function (config) {
+ config.set({
+ basePath: '',
+ frameworks: ['jasmine', '@angular-devkit/build-angular'],
+ plugins: [
+ require('karma-jasmine'),
+ require('karma-chrome-launcher'),
+ require('karma-jasmine-html-reporter'),
+ require('karma-coverage-istanbul-reporter'),
+ require('@angular-devkit/build-angular/plugins/karma')
+ ],
+ client: {
+ clearContext: false // leave Jasmine Spec Runner output visible in browser
+ },
+ coverageIstanbulReporter: {
+ dir: require('path').join(__dirname, '../coverage'),
+ reports: ['html', 'lcovonly'],
+ fixWebpackSourcePaths: true
+ },
+ reporters: ['progress', 'kjhtml'],
+ port: 9876,
+ colors: true,
+ logLevel: config.LOG_INFO,
+ autoWatch: true,
+ browsers: ['Chrome'],
+ singleRun: false
+ });
+}; \ No newline at end of file
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/main.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/main.ts
new file mode 100644
index 0000000..82783c1
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/main.ts
@@ -0,0 +1,34 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import { enableProdMode } from '@angular/core';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { AppModule } from './app/app.module';
+import { environment } from './environments/environment';
+
+if (environment.production) {
+ enableProdMode();
+}
+
+platformBrowserDynamic().bootstrapModule(AppModule)
+ .catch(err => console.log(err));
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/polyfills.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/polyfills.ts
new file mode 100644
index 0000000..d310405
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/polyfills.ts
@@ -0,0 +1,80 @@
+/**
+ * This file includes polyfills needed by Angular and is loaded before the app.
+ * You can add your own extra polyfills to this file.
+ *
+ * This file is divided into 2 sections:
+ * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
+ * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
+ * file.
+ *
+ * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
+ * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
+ * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
+ *
+ * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
+ */
+
+/***************************************************************************************************
+ * BROWSER POLYFILLS
+ */
+
+/** IE9, IE10 and IE11 requires all of the following polyfills. **/
+// import 'core-js/es6/symbol';
+// import 'core-js/es6/object';
+// import 'core-js/es6/function';
+// import 'core-js/es6/parse-int';
+// import 'core-js/es6/parse-float';
+// import 'core-js/es6/number';
+// import 'core-js/es6/math';
+// import 'core-js/es6/string';
+// import 'core-js/es6/date';
+// import 'core-js/es6/array';
+// import 'core-js/es6/regexp';
+// import 'core-js/es6/map';
+// import 'core-js/es6/weak-map';
+// import 'core-js/es6/set';
+
+/** IE10 and IE11 requires the following for NgClass support on SVG elements */
+// import 'classlist.js'; // Run `npm install --save classlist.js`.
+
+/** IE10 and IE11 requires the following for the Reflect API. */
+// import 'core-js/es6/reflect';
+
+
+/** Evergreen browsers require these. **/
+// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
+import 'core-js/es7/reflect';
+
+
+/**
+ * Web Animations `@angular/platform-browser/animations`
+ * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
+ * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
+ **/
+// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
+
+/**
+ * By default, zone.js will patch all possible macroTask and DomEvents
+ * user can disable parts of macroTask/DomEvents patch by setting following flags
+ */
+
+ // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
+ // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
+ // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
+
+ /*
+ * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
+ * with the following flag, it will bypass `zone.js` patch for IE/Edge
+ */
+// (window as any).__Zone_enable_cross_context_check = true;
+
+/***************************************************************************************************
+ * Zone JS is required by default for Angular itself.
+ */
+import 'zone.js/dist/zone'; // Included with Angular CLI.
+
+
+
+/***************************************************************************************************
+ * APPLICATION IMPORTS
+ */
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/styles.scss b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/styles.scss
new file mode 100644
index 0000000..8457059
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/styles.scss
@@ -0,0 +1,73 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+@import '~@angular/material/prebuilt-themes/deeppurple-amber.css'; // @import '~bootstrap/dist/css/bootstrap.min.css';
+/* You can add global styles to this file, and also import other style files */
+
+body {
+ margin: 0;
+ background: #F2F2F2;
+ font-family: 'Montserrat', sans-serif;
+ height: 100vh;
+}
+
+#container {
+ display: grid;
+ grid-template-columns: 70px auto;
+ height: 100%;
+
+ #content {
+ padding: 30px 50px;
+
+ ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+
+ li {
+ background: #fff;
+ border-radius: 8px;
+ padding: 20px;
+ margin-bottom: 8px;
+
+ a {
+ font-size: 1.5em;
+ text-decoration: none;
+ font-weight: bold;
+ color: #00A8FF;
+ }
+
+ ul {
+ margin-top: 20px;
+
+ li {
+ padding: 0;
+
+ a {
+ font-size: 1em;
+ font-weight: 300;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/test.ts b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/test.ts
new file mode 100644
index 0000000..6118eb2
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/test.ts
@@ -0,0 +1,40 @@
+/**
+============LICENSE_START=======================================================
+ Copyright (C) 2018 Ericsson. All rights reserved.
+================================================================================
+Licensed 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.
+
+SPDX-License-Identifier: Apache-2.0
+============LICENSE_END=========================================================
+
+@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+*/
+
+import 'zone.js/dist/zone-testing';
+import { getTestBed } from '@angular/core/testing';
+import {
+ BrowserDynamicTestingModule,
+ platformBrowserDynamicTesting
+} from '@angular/platform-browser-dynamic/testing';
+
+declare const require: any;
+
+// First, initialize the Angular testing environment.
+getTestBed().initTestEnvironment(
+ BrowserDynamicTestingModule,
+ platformBrowserDynamicTesting()
+);
+// Then we find all the tests.
+const context = require.context('./', true, /\.spec\.ts$/);
+// And load the modules.
+context.keys().map(context);
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/tsconfig.app.json b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/tsconfig.app.json
new file mode 100644
index 0000000..722c370
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/tsconfig.app.json
@@ -0,0 +1,12 @@
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../out-tsc/app",
+ "module": "es2015",
+ "types": []
+ },
+ "exclude": [
+ "src/test.ts",
+ "**/*.spec.ts"
+ ]
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/tsconfig.spec.json b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/tsconfig.spec.json
new file mode 100644
index 0000000..8f7cede
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/tsconfig.spec.json
@@ -0,0 +1,19 @@
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../out-tsc/spec",
+ "module": "commonjs",
+ "types": [
+ "jasmine",
+ "node"
+ ]
+ },
+ "files": [
+ "test.ts",
+ "polyfills.ts"
+ ],
+ "include": [
+ "**/*.spec.ts",
+ "**/*.d.ts"
+ ]
+}
diff --git a/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/tslint.json b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/tslint.json
new file mode 100644
index 0000000..52e2c1a
--- /dev/null
+++ b/so-admin-cockpit-monitoring-workflow/so-admin-cockpit-monitoring-workflow-ui/src/main/frontend/src/tslint.json
@@ -0,0 +1,17 @@
+{
+ "extends": "../tslint.json",
+ "rules": {
+ "directive-selector": [
+ true,
+ "attribute",
+ "app",
+ "camelCase"
+ ],
+ "component-selector": [
+ true,
+ "element",
+ "app",
+ "kebab-case"
+ ]
+ }
+}