"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
"dev": true
},
+ "ngx-spinner": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/ngx-spinner/-/ngx-spinner-6.1.2.tgz",
+ "integrity": "sha512-j/R8T5vKvsLLib1pTxKLYK3GYAFXw5VoUJmaTlcocO6Yi4qIypfhmw9PX9triy7hWVGPu6cUzVs7g9cEG9OYBA==",
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
"no-case": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
"bpmn-js": "^2.4.1",
"core-js": "^2.5.4",
"jquery": "^3.3.1",
+ "ngx-spinner": "^6.1.2",
"rxjs": "^6.0.0",
"toastr": "^2.1.4",
"zone.js": "^0.8.26"
import { MatDatepickerModule } from '@angular/material/datepicker';\r
import { MatNativeDateModule } from '@angular/material';\r
import { MatCardModule } from '@angular/material/card';\r
+import { NgxSpinnerModule } from 'ngx-spinner';\r
\r
@NgModule({\r
declarations: [\r
MatInputModule,\r
MatDatepickerModule,\r
MatNativeDateModule,\r
- MatCardModule\r
+ MatCardModule,\r
+ NgxSpinnerModule\r
],\r
providers: [ToastrNotificationService],\r
bootstrap: [AppComponent]\r
</mat-tab-group>\r
</div>\r
</div>\r
+\r
+<ngx-spinner bdColor="rgba(51, 51, 51, 0.8)" size="large" color="#00285f" type="ball-spin-clockwise-fade-rotating"></ngx-spinner>\r
import { MatTabsModule } from '@angular/material/tabs';\r
import { VarInstance } from '../model/variableInstance.model';\r
import { ToastrNotificationService } from '../toastr-notification-service.service';\r
+import { NgxSpinnerService } from 'ngx-spinner';\r
\r
@Component({\r
selector: 'app-details',\r
\r
displayedColumnsVariable = ['name', 'type', 'value'];\r
\r
- constructor(private route: ActivatedRoute, private data: DataService, private popup: ToastrNotificationService, private router: Router) { }\r
+ constructor(private route: ActivatedRoute, private data: DataService, private popup: ToastrNotificationService,\r
+ private router: Router, private spinner: NgxSpinnerService) { }\r
\r
getActInst(procInstId: string) {\r
this.data.getActivityInstance(procInstId).subscribe(\r
}\r
\r
displayCamundaflow(bpmnXml, activities: ACTINST[], r: Router) {\r
+ this.spinner.show();\r
\r
this.bpmnViewer.importXML(bpmnXml, (error) => {\r
if (error) {\r
console.error('Unable to load BPMN flow ', error);\r
this.popup.error('Unable to load BPMN flow ');\r
+ this.spinner.hide();\r
} else {\r
+ this.spinner.hide();\r
let canvas = this.bpmnViewer.get('canvas');\r
var eventBus = this.bpmnViewer.get('eventBus');\r
eventBus.on('element.click', function(e) {\r
if (a.activityId == e.element.id && a.calledProcessInstanceId !== null) {\r
console.log("will drill down to : " + a.calledProcessInstanceId);\r
r.navigate(['/details/' + a.calledProcessInstanceId]);\r
+ this.spinner.show();\r
}\r
});\r
});\r
<input matInput #searchValueRI type="text" [(ngModel)]="searchData.requestId" placeholder="Request Id">\r
</mat-form-field>\r
\r
- <!-- Angular Start Date Picker -->\r
- <mat-form-field class="startDate">\r
- <input matInput #startDate [matDatepicker]="picker" [(ngModel)]="searchData.startDate" placeholder="Choose a start date">\r
- <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>\r
- <mat-datepicker #picker></mat-datepicker>\r
- </mat-form-field>\r
-\r
- <!-- Dropdown box for Start Hour selection -->\r
- <mat-form-field class="selectHour">\r
- <mat-select class="formatBox" [(ngModel)]="searchData.selectedStartHour" name="hourFrom" placeholder="Select Hour">\r
- <mat-option *ngFor="let option of hourOptions" [value]="option">{{option}}</mat-option>\r
- </mat-select>\r
- </mat-form-field>\r
-\r
- <!-- Dropdown box for Start Minute selection -->\r
- <mat-form-field class="selectMinute">\r
- <mat-select class="formatBox" [(ngModel)]="searchData.selectedStartMinute" name="minuteFrom" placeholder="Select Minute">\r
- <mat-option *ngFor="let option of minuteOptions" [value]="option">{{option}}</mat-option>\r
- </mat-select>\r
- </mat-form-field>\r
+ <!-- Angular Start Date Picker -->\r
+ <mat-form-field class="startDate">\r
+ <input matInput #startDate [matDatepicker]="picker" [(ngModel)]="searchData.startDate" placeholder="Choose a start date">\r
+ <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>\r
+ <mat-datepicker #picker></mat-datepicker>\r
+ </mat-form-field>\r
+\r
+ <!-- Dropdown box for Start Hour selection -->\r
+ <mat-form-field class="selectHour">\r
+ <mat-select class="formatBox" [(ngModel)]="searchData.selectedStartHour" name="hourFrom" placeholder="Select Hour">\r
+ <mat-option *ngFor="let option of hourOptions" [value]="option">{{option}}</mat-option>\r
+ </mat-select>\r
+ </mat-form-field>\r
+\r
+ <!-- Dropdown box for Start Minute selection -->\r
+ <mat-form-field class="selectMinute">\r
+ <mat-select class="formatBox" [(ngModel)]="searchData.selectedStartMinute" name="minuteFrom" placeholder="Select Minute">\r
+ <mat-option *ngFor="let option of minuteOptions" [value]="option">{{option}}</mat-option>\r
+ </mat-select>\r
+ </mat-form-field>\r
</div>\r
\r
<!-- Dropdown Filter and TextBox for Service Name -->\r
<input matInput #searchValueSN type="text" [(ngModel)]="searchData.serviceInstanceName" placeholder="Service Name">\r
</mat-form-field>\r
\r
- <!-- Angular End Date Picker -->\r
- <mat-form-field class="endDate">\r
- <input matInput #endDate [matDatepicker]="endpicker" [(ngModel)]="searchData.endDate" placeholder="Choose an end date">\r
- <mat-datepicker-toggle matSuffix [for]="endpicker"></mat-datepicker-toggle>\r
- <mat-datepicker #endpicker></mat-datepicker>\r
- </mat-form-field>\r
-\r
- <!-- Dropdown box for End Hour selection -->\r
- <mat-form-field class="selectHour">\r
- <mat-select class="formatBox" [(ngModel)]="searchData.selectedEndHour" name="hourTo" placeholder="Select Hour">\r
- <mat-option *ngFor="let option of hourOptions" [value]="option">{{option}}</mat-option>\r
- </mat-select>\r
- </mat-form-field>\r
-\r
- <!-- Dropdown box for End Minute selection -->\r
- <mat-form-field class="selectMinute">\r
- <mat-select class="formatBox" [(ngModel)]="searchData.selectedEndMinute" name="minuteTo" placeholder="Select Minute">\r
- <mat-option *ngFor="let option of minuteOptions" [value]="option">{{option}}</mat-option>\r
- </mat-select>\r
- </mat-form-field>\r
+ <!-- Angular End Date Picker -->\r
+ <mat-form-field class="endDate">\r
+ <input matInput #endDate [matDatepicker]="endpicker" [(ngModel)]="searchData.endDate" placeholder="Choose an end date">\r
+ <mat-datepicker-toggle matSuffix [for]="endpicker"></mat-datepicker-toggle>\r
+ <mat-datepicker #endpicker></mat-datepicker>\r
+ </mat-form-field>\r
+\r
+ <!-- Dropdown box for End Hour selection -->\r
+ <mat-form-field class="selectHour">\r
+ <mat-select class="formatBox" [(ngModel)]="searchData.selectedEndHour" name="hourTo" placeholder="Select Hour">\r
+ <mat-option *ngFor="let option of hourOptions" [value]="option">{{option}}</mat-option>\r
+ </mat-select>\r
+ </mat-form-field>\r
+\r
+ <!-- Dropdown box for End Minute selection -->\r
+ <mat-form-field class="selectMinute">\r
+ <mat-select class="formatBox" [(ngModel)]="searchData.selectedEndMinute" name="minuteTo" placeholder="Select Minute">\r
+ <mat-option *ngFor="let option of minuteOptions" [value]="option">{{option}}</mat-option>\r
+ </mat-select>\r
+ </mat-form-field>\r
</div>\r
\r
<!-- Dropdown Filter for Status -->\r
\r
<mat-tab label="Service Statistics">\r
<div id="servStats">\r
- <p>Total: {{ totalVal }}</p>\r
- <hr/>\r
- <p>Complete: {{ completeVal }}</p>\r
- <p><b> {{ percentageComplete }}%</b></p>\r
- <hr/>\r
- <p>Failed: {{ failedVal }}</p>\r
- <p><b> {{ percentageFailed }}%</b></p>\r
- <hr/>\r
- <p>In Progress: {{ inProgressVal }}</p>\r
- <hr/>\r
- <p>Pending: {{ pendingVal }}</p>\r
- <hr/>\r
- <p>Unlocked: {{ unlockedVal }}</p>\r
+ <table class="statsTable">\r
+ <tbody>\r
+ <tr>\r
+ <td>Total: {{ totalVal }}</td>\r
+ <td></td>\r
+ </tr>\r
+ <tr>\r
+ <td>Complete: {{ completeVal }}</td>\r
+ <td> {{ percentageComplete }}%</td>\r
+ </tr>\r
+ <tr>\r
+ <td>Failed: {{ failedVal }}</td>\r
+ <td> {{ percentageFailed }}%</td>\r
+ </tr>\r
+ <tr>\r
+ <td>In Progress: {{ inProgressVal }}</td>\r
+ <td> {{ percentageInProg }}%</td>\r
+ </tr>\r
+ <tr>\r
+ <td>Pending: {{ pendingVal }}</td>\r
+ <td> {{ percentagePending }}%</td>\r
+ </tr>\r
+ <tr>\r
+ <td>Unlocked: {{ unlockedVal }}</td>\r
+ <td> {{ percentageUnlocked }}%</td>\r
+ </tr>\r
+ </tbody>\r
+ </table>\r
</div>\r
</mat-tab>\r
</mat-tab-group>\r
</div>\r
</div>\r
\r
+<ngx-spinner bdColor="rgba(51, 51, 51, 0.8)" size="large" color="#00285f" type="ball-spin-clockwise-fade-rotating"></ngx-spinner>\r
<router-outlet></router-outlet>\r
\r
@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com\r
*/\r
-\r
@import "~@angular/material/prebuilt-themes/indigo-pink.css";\r
\r
.searchArea {\r
}\r
\r
.fa {\r
- float: left;\r
+ float: left;\r
width: 120px;\r
padding: 10px;\r
background: #2196F3;\r
display: inline-flex;\r
}\r
\r
-.startDate, .endDate{\r
+.endDate,\r
+.startDate {\r
margin-left: 90px;\r
width: 140px;\r
}\r
\r
-.selectHour, .selectMinute{\r
+.selectHour,\r
+.selectMinute {\r
margin-left: 30px;\r
- width: 100px\r
+ width: 100px;\r
}\r
\r
-#servStats{\r
+#servStats {\r
background-color: white;\r
padding: 10px;\r
font-size: 17px;\r
font-family: 'Montserrat', sans-serif;\r
}\r
\r
-hr {\r
- display: block;\r
- height: 1px;\r
- border: 0;\r
- border-top: 1px solid #ccc;\r
- margin: 1em 0;\r
- padding: 0;\r
+.statsTable {\r
+ td {\r
+ padding: 12px 80px 12px 12px;\r
+ text-align: left;\r
+ border-bottom: 1px solid #ccc;\r
+ }\r
}\r
import { MatDatepickerModule } from '@angular/material/datepicker';
import { FormControl } from '@angular/forms';
import { SearchRequest } from '../model/SearchRequest.model';
-import { ViewChild } from '@angular/core';
import { ElementRef } from '@angular/core';
import { Input } from '@angular/core';
+import { NgxSpinnerService } from 'ngx-spinner';
@Component({
selector: 'app-home',
unlockedVal = 0;
percentageComplete = 0;
percentageFailed = 0;
+ percentageInProg = 0;
+ percentagePending = 0;
+ percentageUnlocked = 0;
options = [{ name: "EQUAL", value: "EQ" }, { name: "NOT EQUAL", value: "NEQ" }, { name: "LIKE", value: "LIKE" }];
statusOptions = [{ name: "ALL", value: "ALL" }, { name: "COMPLETE", value: "COMPLETE" }, { name: "IN_PROGRESS", value: "IN_PROGRESS" },
displayedColumns = ['requestId', 'serviceInstanceId', 'serviceIstanceName', 'networkId', 'requestStatus', 'serviceType', 'startTime', 'endTime'];
constructor(private route: ActivatedRoute, private data: DataService,
- private router: Router, private popup: ToastrNotificationService) {
+ 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.retrieveInstance(result.getFilters(), result.getStartTimeInMilliseconds(), result.getEndTimeInMilliseconds())
.subscribe((data: Process[]) => {
+ this.spinner.hide();
this.processData = data;
- this.popup.info("Number of records found: " + data.length);
+ this.popup.info("Number of records found: " + data.length)
+
// Calculate Statistics for Service Statistics tab
this.completeVal = this.processData.filter(i => i.requestStatus === "COMPLETE").length;
this.inProgressVal = this.processData.filter(i => i.requestStatus === "IN_PROGRESS").length;
this.pendingVal = this.processData.filter(i => i.requestStatus === "PENDING").length;
this.unlockedVal = this.processData.filter(i => i.requestStatus === "UNLOCKED").length;
this.totalVal = this.processData.length;
- this.percentageComplete = Math.round(((this.completeVal / this.totalVal) * 100) * 100) / 100;
- this.percentageFailed = Math.round(((this.failedVal / this.totalVal) * 100) * 100) / 100;
+ // 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();
});
}
getProcessIsntanceId(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);
}
});