Add functionality to truncate amount of instances 52/6152/1
authorychacon <yennifer.chacon@est.tech>
Thu, 27 May 2021 08:59:56 +0000 (10:59 +0200)
committerychacon <yennifer.chacon@est.tech>
Thu, 27 May 2021 08:59:56 +0000 (10:59 +0200)
Issue-ID: NONRTRIC-511
Signed-off-by: ychacon <yennifer.chacon@est.tech>
Change-Id: I9ef3425d306c5d56b46a81982f0dc57400513624

webapp-frontend/src/app/policy/policy-instance/policy-instance.component.html
webapp-frontend/src/app/policy/policy-instance/policy-instance.component.spec.ts
webapp-frontend/src/app/policy/policy-instance/policy-instance.component.ts
webapp-frontend/src/app/policy/policy.module.ts

index 3203c0d..db676a6 100644 (file)
     <button id="refreshButton" mat-icon-button color="primary" (click)="refreshTable()">
         <mat-icon id="refreshIcon">refresh</mat-icon>
     </button>
+    <div class="spinner-container" style="display: flex; justify-content: center; align-items: center;"
+        *ngIf="loading$ | async">
+        <mat-spinner></mat-spinner>
+    </div>
+    <div id="truncated" *ngIf="truncated" class="alert">
+        Too many instances! Only {{slice}} results will be shown.
+    </div>
 </div>
 
 <mat-table class="instances-table mat-elevation-z8" id="policiesTable" [dataSource]="instanceDataSource" matSort
index baaa80a..4a50046 100644 (file)
@@ -186,27 +186,24 @@ describe("PolicyInstanceComponent", () => {
     });
 
     it("should contain number of instances heading and value, create and refresh buttons, and policies table", async () => {
-      const instancesHeading = hostFixture.debugElement.nativeElement.querySelector(
-        "div"
-      );
+      const instancesHeading =
+        hostFixture.debugElement.nativeElement.querySelector("div");
       expect(instancesHeading.innerText).toContain("Number of instances: 2");
 
       const createButton: MatButtonHarness = await loader.getHarness(
         MatButtonHarness.with({ selector: "#createButton" })
       );
       expect(createButton).toBeTruthy();
-      const createIcon = hostFixture.debugElement.nativeElement.querySelector(
-        "#createIcon"
-      );
+      const createIcon =
+        hostFixture.debugElement.nativeElement.querySelector("#createIcon");
       expect(createIcon.innerText).toContain("add_box");
 
       const refreshButton: MatButtonHarness = await loader.getHarness(
         MatButtonHarness.with({ selector: "#refreshButton" })
       );
       expect(refreshButton).toBeTruthy();
-      const refreshIcon = hostFixture.debugElement.nativeElement.querySelector(
-        "#refreshIcon"
-      );
+      const refreshIcon =
+        hostFixture.debugElement.nativeElement.querySelector("#refreshIcon");
       expect(refreshIcon.innerText).toContain("refresh");
 
       const policiesTable = await loader.getHarness(
@@ -309,7 +306,7 @@ describe("PolicyInstanceComponent", () => {
       const lastModifiedCell = (await firstRow.getCells())[3];
       (await lastModifiedCell.host()).click();
 
-      // Totally unnecessary call just to make the bloody framework count the number of calls to the spy correctly!
+      // Totally unnecessary call just to make the framework count the number of calls to the spy correctly!
       await policiesTable.getRows();
 
       expect(componentUnderTest.modifyInstance).toHaveBeenCalledTimes(4);
@@ -494,24 +491,22 @@ describe("PolicyInstanceComponent", () => {
     it("should not sort when click in filter inputs", async () => {
       spyOn(componentUnderTest, "stopSort").and.callThrough();
 
-      const idFilterInputDiv = hostFixture.debugElement.nativeElement.querySelector(
-        "#idSortStop"
-      );
+      const idFilterInputDiv =
+        hostFixture.debugElement.nativeElement.querySelector("#idSortStop");
       idFilterInputDiv.click();
 
-      const targetFilterInputDiv = hostFixture.debugElement.nativeElement.querySelector(
-        "#targetSortStop"
-      );
+      const targetFilterInputDiv =
+        hostFixture.debugElement.nativeElement.querySelector("#targetSortStop");
       targetFilterInputDiv.click();
 
-      const ownerFilterInputDiv = hostFixture.debugElement.nativeElement.querySelector(
-        "#ownerSortStop"
-      );
+      const ownerFilterInputDiv =
+        hostFixture.debugElement.nativeElement.querySelector("#ownerSortStop");
       ownerFilterInputDiv.click();
 
-      const lastModifiedFilterInputDiv = hostFixture.debugElement.nativeElement.querySelector(
-        "#lastModifiedSortStop"
-      );
+      const lastModifiedFilterInputDiv =
+        hostFixture.debugElement.nativeElement.querySelector(
+          "#lastModifiedSortStop"
+        );
       lastModifiedFilterInputDiv.click();
 
       expect(componentUnderTest.stopSort).toHaveBeenCalledTimes(4);
@@ -521,6 +516,38 @@ describe("PolicyInstanceComponent", () => {
       expect(eventSpy.stopPropagation).toHaveBeenCalled();
     });
 
+    describe("#truncate data", () => {
+      fit("should verify that data is correctly truncated when needed", async () => {
+        policyServiceSpy.getPolicyInstancesByType.and.returnValue(
+          of(policyInstances)
+        );
+        policyServiceSpy.getPolicyInstance.and.callFake(function (
+          policyId: string
+        ) {
+          return of(policyIdToInstanceMap[policyId]);
+        });
+        policyServiceSpy.getPolicyStatus.and.callFake(function (
+          policyId: string
+        ) {
+          return of(policyIdToStatusMap[policyId]);
+        });
+        compileAndGetComponents();
+        componentUnderTest.slice = 1;
+        componentUnderTest.ngOnInit();
+
+        const policiesTable = await loader.getHarness(
+          MatTableHarness.with({ selector: "#policiesTable" })
+        );
+        const policyRows = await policiesTable.getRows();
+        expect(policyRows.length).toEqual(1);
+        policyRows[0].getCellTextByColumnName().then((values) => {
+          expect(expectedPolicy1Row).toEqual(jasmine.objectContaining(values));
+        });
+
+        expect(componentUnderTest.truncated).toBeTruthy();
+      });
+    });
+
     describe("#sorting", () => {
       it("should verify sort functionality on the table", async () => {
         const sort = await loader.getHarness(MatSortHarness);
index 1649d39..5e29f3a 100644 (file)
@@ -33,7 +33,7 @@ import { BehaviorSubject, forkJoin } from "rxjs";
 import { UiService } from "@services/ui/ui.service";
 import { FormControl, FormGroup } from "@angular/forms";
 import { MatTableDataSource } from "@angular/material/table";
-import { mergeMap } from "rxjs/operators";
+import { finalize, mergeMap, map } from "rxjs/operators";
 
 @Component({
   selector: "nrcp-policy-instance",
@@ -41,12 +41,16 @@ import { mergeMap } from "rxjs/operators";
   styleUrls: ["./policy-instance.component.scss"],
 })
 export class PolicyInstanceComponent implements OnInit {
+  public slice: number = 1000;
   @Input() policyTypeSchema: PolicyTypeSchema;
   darkMode: boolean;
   instanceDataSource: MatTableDataSource<PolicyInstance>;
   policyInstanceForm: FormGroup;
   private policyInstanceSubject = new BehaviorSubject<PolicyInstance[]>([]);
   policyInstances: PolicyInstance[] = [];
+  private loadingSubject$ = new BehaviorSubject<boolean>(false);
+  public loading$ = this.loadingSubject$.asObservable();
+  public truncated = false;
 
   constructor(
     private policySvc: PolicyService,
@@ -96,9 +100,17 @@ export class PolicyInstanceComponent implements OnInit {
 
   getPolicyInstances() {
     this.policyInstances = [] as PolicyInstance[];
+    this.loadingSubject$.next(true);
     this.policySvc
       .getPolicyInstancesByType(this.policyTypeSchema.id)
       .pipe(
+        map((data) => {
+          if (data.policy_ids.length > this.slice) {
+            this.truncated = true;
+            data.policy_ids = data.policy_ids.slice(0, this.slice);
+          }
+          return data;
+        }),
         mergeMap((policyIds) =>
           forkJoin(
             policyIds.policy_ids.map((id) => {
@@ -108,7 +120,8 @@ export class PolicyInstanceComponent implements OnInit {
               ]);
             })
           )
-        )
+        ),
+        finalize(() => this.loadingSubject$.next(false))
       )
       .subscribe((res) => {
         this.policyInstances = res.map((policy) => {
@@ -178,7 +191,7 @@ export class PolicyInstanceComponent implements OnInit {
 
   hasInstances(): boolean {
     return this.instanceCount() > 0;
-}
+  }
 
   instanceCount(): number {
     return this.policyInstances.length;
@@ -212,6 +225,7 @@ export class PolicyInstanceComponent implements OnInit {
   }
 
   refreshTable() {
+    this.truncated = false;
     this.getPolicyInstances();
   }
 }
index a6a187c..38b9755 100644 (file)
@@ -43,6 +43,7 @@ import { MatButtonModule } from '@angular/material/button';
 import { FlexLayoutModule } from '@angular/flex-layout';
 import { MatCardModule } from '@angular/material/card';
 import { MatTooltipModule } from '@angular/material/tooltip';
+import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
 
 const routes:Routes = [
   {path: 'policy', component: PolicyControlComponent}
@@ -69,6 +70,7 @@ const routes:Routes = [
     MatFormFieldModule,
     MatIconModule,
     MatInputModule,
+    MatProgressSpinnerModule,
     MatSelectModule,
     MatSortModule,
     MaterialDesignFrameworkModule,