From: elinuxhenrik Date: Wed, 31 Mar 2021 15:26:54 +0000 (+0200) Subject: Simplify PolicyInstanceComponent X-Git-Tag: 2.2.0~41^2 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=cd497d449fc933316aa3e3c2aace85fc88e2a0a8;p=portal%2Fnonrtric-controlpanel.git Simplify PolicyInstanceComponent Change-Id: I56357272cf4a1f206184b090b6cbcfbe262d7f41 Issue-ID: NONRTRIC-472 Signed-off-by: elinuxhenrik --- diff --git a/webapp-frontend/src/app/policy/policy-instance/policy-instance.component.html b/webapp-frontend/src/app/policy/policy-instance/policy-instance.component.html index 8c9f5c5..e6d483f 100644 --- a/webapp-frontend/src/app/policy/policy-instance/policy-instance.component.html +++ b/webapp-frontend/src/app/policy/policy-instance/policy-instance.component.html @@ -27,7 +27,7 @@ - @@ -110,12 +110,7 @@ No records found. - + - - - -
\ No newline at end of file diff --git a/webapp-frontend/src/app/policy/policy-instance/policy-instance.component.spec.ts b/webapp-frontend/src/app/policy/policy-instance/policy-instance.component.spec.ts new file mode 100644 index 0000000..2546b6d --- /dev/null +++ b/webapp-frontend/src/app/policy/policy-instance/policy-instance.component.spec.ts @@ -0,0 +1,55 @@ +/*- + * ========================LICENSE_START================================= + * O-RAN-SC + * %% + * Copyright (C) 2020 Nordix Foundation + * %% + * 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. + * ========================LICENSE_END=================================== + */ + +import { async, ComponentFixture } from "@angular/core/testing"; +import { PolicyService } from "@app/services/policy/policy.service"; +import { PolicyInstanceComponent } from "./policy-instance.component"; + +describe("PolicyInstanceComponent", () => { + let component: PolicyInstanceComponent; + let fixture: ComponentFixture; + + // beforeEach(async(() => { + // policyDataSourceSpy = jasmine.createSpyObj("PolicyInstanceDataSource", ["getPolicyType"]); + // const policyTypeSchema = JSON.parse( + // '{"title": "1", "description": "Type 1 policy type"}' + // ); + // const policyType = { policy_schema: policyTypeSchema } as PolicyType; + // policyDataSourceSpy.getPolicyType.and.returnValue(of(policyType)); + + // TestBed.configureTestingModule({ + // declarations: [ + // PolicyTypeComponent, + // MockComponent(PolicyInstanceComponent), + // ], + // providers: [{ provide: PolicyService, useValue: policyDataSourceSpy }], + // }).compileComponents(); + // })); + + // beforeEach(() => { + // fixture = TestBed.createComponent(PolicyTypeComponent); + // component = fixture.componentInstance; + // fixture.detectChanges(); + // }); + + // it("should create", () => { + // expect(component).toBeTruthy(); + // }); +}) \ No newline at end of file diff --git a/webapp-frontend/src/app/policy/policy-instance/policy-instance.component.ts b/webapp-frontend/src/app/policy/policy-instance/policy-instance.component.ts index 700e929..8442c23 100644 --- a/webapp-frontend/src/app/policy/policy-instance/policy-instance.component.ts +++ b/webapp-frontend/src/app/policy/policy-instance/policy-instance.component.ts @@ -18,192 +18,243 @@ * ========================LICENSE_END=================================== */ -import { MatSort, Sort } from '@angular/material/sort'; -import { Component, OnInit, ViewChild, Input, AfterViewInit } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { PolicyTypeSchema } from '@interfaces/policy.types'; -import { PolicyInstanceDataSource } from './policy-instance.datasource'; -import { ErrorDialogService } from '@services/ui/error-dialog.service'; -import { NotificationService } from '@services/ui/notification.service'; -import { PolicyService } from '@services/policy/policy.service'; -import { ConfirmDialogService } from '@services/ui/confirm-dialog.service'; -import { PolicyInstance } from '@interfaces/policy.types'; -import { PolicyInstanceDialogComponent } from '../policy-instance-dialog/policy-instance-dialog.component'; -import { getPolicyDialogProperties } from '../policy-instance-dialog/policy-instance-dialog.component'; -import { HttpErrorResponse, HttpResponse } from '@angular/common/http'; -import { BehaviorSubject, Observable } from 'rxjs'; -import { UiService } from '@services/ui/ui.service'; -import { FormControl, FormGroup } from '@angular/forms'; -import { MatTableDataSource } from '@angular/material/table'; +import { Sort } from "@angular/material/sort"; +import { Component, OnInit, Input } from "@angular/core"; +import { MatDialog } from "@angular/material/dialog"; +import { PolicyTypeSchema } from "@interfaces/policy.types"; +import { ErrorDialogService } from "@services/ui/error-dialog.service"; +import { NotificationService } from "@services/ui/notification.service"; +import { PolicyService } from "@services/policy/policy.service"; +import { ConfirmDialogService } from "@services/ui/confirm-dialog.service"; +import { PolicyInstance } from "@interfaces/policy.types"; +import { PolicyInstanceDialogComponent } from "../policy-instance-dialog/policy-instance-dialog.component"; +import { getPolicyDialogProperties } from "../policy-instance-dialog/policy-instance-dialog.component"; +import { HttpErrorResponse, HttpResponse } from "@angular/common/http"; +import { BehaviorSubject, Observable } from "rxjs"; +import { UiService } from "@services/ui/ui.service"; +import { FormControl, FormGroup } from "@angular/forms"; +import { MatTableDataSource } from "@angular/material/table"; class PolicyTypeInfo { - constructor(public type: PolicyTypeSchema) { } + constructor(public type: PolicyTypeSchema) {} isExpanded: BehaviorSubject = new BehaviorSubject(false); } @Component({ - selector: 'nrcp-policy-instance', - templateUrl: './policy-instance.component.html', - styleUrls: ['./policy-instance.component.scss'] + selector: "nrcp-policy-instance", + templateUrl: "./policy-instance.component.html", + styleUrls: ["./policy-instance.component.scss"], }) +export class PolicyInstanceComponent implements OnInit { + @Input() policyTypeSchema: PolicyTypeSchema; + @Input() expanded: Observable; + policyInstances: PolicyInstance[] = []; + private policyInstanceSubject = new BehaviorSubject([]); + policyTypeInfo = new Map(); + instanceDataSource: MatTableDataSource = new MatTableDataSource(); + policyInstanceForm: FormGroup; + darkMode: boolean; + constructor( + private policySvc: PolicyService, + private dialog: MatDialog, + private errorDialogService: ErrorDialogService, + private notificationService: NotificationService, + private confirmDialogService: ConfirmDialogService, + private ui: UiService + ) { + this.policyInstanceForm = new FormGroup({ + id: new FormControl(""), + target: new FormControl(""), + owner: new FormControl(""), + lastModified: new FormControl(""), + }); + } -export class PolicyInstanceComponent implements OnInit, AfterViewInit { - policyInstanceDataSource: PolicyInstanceDataSource; - @Input() policyTypeSchema: PolicyTypeSchema; - @Input() expanded: Observable; - @ViewChild(MatSort, { static: true }) sort: MatSort; - policyTypeInfo = new Map(); - instanceDataSource: MatTableDataSource = new MatTableDataSource(); - policyInstanceForm: FormGroup; - darkMode: boolean; - - constructor( - private policySvc: PolicyService, - private dialog: MatDialog, - private errorDialogService: ErrorDialogService, - private notificationService: NotificationService, - private confirmDialogService: ConfirmDialogService, - private ui: UiService) { - this.policyInstanceForm = new FormGroup({ - id: new FormControl(''), - target: new FormControl(''), - owner: new FormControl(''), - lastModified: new FormControl('') - }) - } + ngOnInit() { + this.expanded.subscribe((isExpanded: boolean) => this.onExpand(isExpanded)); - ngOnInit() { - this.policyInstanceDataSource = new PolicyInstanceDataSource(this.policySvc, this.sort, this.notificationService, this.policyTypeSchema.id); - this.expanded.subscribe((isExpanded: boolean) => this.onExpand(isExpanded)); - - this.policyInstanceDataSource.connect().subscribe((data) => { - this.instanceDataSource.data = data; - }) - - this.policyInstanceForm.valueChanges.subscribe(value => { - const filter = {...value, id: value.id.trim().toLowerCase()} as string; - this.instanceDataSource.filter = filter; - }); - - this.instanceDataSource.filterPredicate = ((data: PolicyInstance, filter) => { - return this.isDataIncluding(data.policy_id, filter.id) - && this.isDataIncluding(data.ric_id, filter.target) - && this.isDataIncluding(data.service_id, filter.owner) - && this.isDataIncluding(data.lastModified, filter.lastModified); - }) as (data: PolicyInstance, filter: any) => boolean; - - this.ui.darkModeState.subscribe((isDark) => { - this.darkMode = isDark; - }); - } + this.getPolicyInstances(); + this.policyInstanceSubject.subscribe((data) => { + this.instanceDataSource.data = data; + }); - compare(a: any, b: any, isAsc: boolean) { - return (a < b ? -1 : 1) * (isAsc ? 1 : -1); - } + this.policyInstanceForm.valueChanges.subscribe((value) => { + const filter = { ...value, id: value.id.trim().toLowerCase() } as string; + this.instanceDataSource.filter = filter; + }); - stopSort(event: any){ - event.stopPropagation(); - } + this.instanceDataSource.filterPredicate = (( + data: PolicyInstance, + filter + ) => { + return ( + this.isDataIncluding(data.policy_id, filter.id) && + this.isDataIncluding(data.ric_id, filter.target) && + this.isDataIncluding(data.service_id, filter.owner) && + this.isDataIncluding(data.lastModified, filter.lastModified) + ); + }) as (data: PolicyInstance, filter: any) => boolean; - isDataIncluding(data: string, filter: string) : boolean { - return !filter || data.toLowerCase().includes(filter); - } - - ngAfterViewInit() { - this.policyInstanceDataSource.sort = this.sort; - } + this.ui.darkModeState.subscribe((isDark) => { + this.darkMode = isDark; + }); + } - private onExpand(isExpanded: boolean) { - if (isExpanded) { - this.policyInstanceDataSource.getPolicyInstances(); + getPolicyInstances() { + this.policyInstances = [] as PolicyInstance[]; + this.policySvc + .getPolicyInstancesByType(this.policyTypeSchema.id) + .subscribe((policies) => { + if (policies.policy_ids.length != 0) { + policies.policy_ids.forEach((policyId) => { + this.policySvc + .getPolicyInstance(policyId) + .subscribe((policyInstance) => { + this.policySvc + .getPolicyStatus(policyId) + .subscribe((policyStatus) => { + policyInstance.lastModified = policyStatus.last_modified; + }); + this.policyInstances.push(policyInstance); + }); + this.policyInstanceSubject.next(this.policyInstances); + }); } - } + }); + } - private isSchemaEmpty(): boolean { - return this.policyTypeSchema.schemaObject === '{}'; - } + getSortedData(sort: Sort) { + const data = this.instanceDataSource.data; + data.sort((a, b) => { + const isAsc = sort.direction === "asc"; + switch (sort.active) { + case "instanceId": + return compare(a.policy_id, b.policy_id, isAsc); + case "ric": + return compare(a.ric_id, b.ric_id, isAsc); + case "service": + return compare(a.service_id, b.service_id, isAsc); + case "lastModified": + return compare(a.lastModified, b.lastModified, isAsc); + default: + return 0; + } + }); + this.instanceDataSource.data = data; + } - modifyInstance(instance: PolicyInstance): void { - this.policySvc.getPolicyInstance(instance.policy_id).subscribe( - (refreshedJson: any) => { - instance = refreshedJson; - this.dialog.open( - PolicyInstanceDialogComponent, - getPolicyDialogProperties(this.policyTypeSchema, instance, this.darkMode)).afterClosed().subscribe( - (_: any) => { - this.policyInstanceDataSource.getPolicyInstances(); - } - ); - }, - (httpError: HttpErrorResponse) => { - this.notificationService.error('Could not refresh instance. Please try again.' + httpError.message); - } - ); - } + stopSort(event: any) { + event.stopPropagation(); + } - hasInstances(): boolean { - return this.policyInstanceDataSource.rowCount > 0; - } + isDataIncluding(data: string, filter: string): boolean { + return !filter || data.toLowerCase().includes(filter); + } - nbInstances(): number { - return this.policyInstanceDataSource.policyInstances.length; + private onExpand(isExpanded: boolean) { + if (isExpanded) { + this.getPolicyInstances(); } + } - toLocalTime(utcTime: string): string { - const date = new Date(utcTime); - const toutc = date.toUTCString(); - return new Date(toutc + ' UTC').toLocaleString(); + private isSchemaEmpty(): boolean { + return this.policyTypeSchema.schemaObject === "{}"; + } - } - - createPolicyInstance(policyTypeSchema: PolicyTypeSchema): void { - let dialogRef = this.dialog.open(PolicyInstanceDialogComponent, - getPolicyDialogProperties(policyTypeSchema, null, this.darkMode)); - const info: PolicyTypeInfo = this.getPolicyTypeInfo(policyTypeSchema); - dialogRef.afterClosed().subscribe( - (_) => { - info.isExpanded.next(info.isExpanded.getValue()); - } + modifyInstance(instance: PolicyInstance): void { + this.policySvc.getPolicyInstance(instance.policy_id).subscribe( + (refreshedJson: any) => { + instance = refreshedJson; + this.dialog + .open( + PolicyInstanceDialogComponent, + getPolicyDialogProperties( + this.policyTypeSchema, + instance, + this.darkMode + ) + ) + .afterClosed() + .subscribe((_: any) => { + this.getPolicyInstances(); + }); + }, + (httpError: HttpErrorResponse) => { + this.notificationService.error( + "Could not refresh instance. Please try again." + httpError.message ); - } + } + ); + } - deleteInstance(instance: PolicyInstance): void { - this.confirmDialogService - .openConfirmDialog('Are you sure you want to delete this policy instance?') - .afterClosed().subscribe( - (res: any) => { - if (res) { - this.policySvc.deletePolicy(instance.policy_id) - .subscribe( - (response: HttpResponse) => { - switch (response.status) { - case 204: - this.notificationService.success('Delete succeeded!'); - this.policyInstanceDataSource.getPolicyInstances(); - break; - default: - this.notificationService.warn('Delete failed ' + response.status + ' ' + response.body); - } - }, - (error: HttpErrorResponse) => { - this.errorDialogService.displayError(error.statusText + ', ' + error.error); - }); - } - }); - } + nbInstances(): number { + return this.policyInstances.length; + } + + toLocalTime(utcTime: string): string { + const date = new Date(utcTime); + const toutc = date.toUTCString(); + return new Date(toutc + " UTC").toLocaleString(); + } + + createPolicyInstance(policyTypeSchema: PolicyTypeSchema): void { + let dialogRef = this.dialog.open( + PolicyInstanceDialogComponent, + getPolicyDialogProperties(policyTypeSchema, null, this.darkMode) + ); + const info: PolicyTypeInfo = this.getPolicyTypeInfo(policyTypeSchema); + dialogRef.afterClosed().subscribe((_) => { + info.isExpanded.next(info.isExpanded.getValue()); + }); + } - getPolicyTypeInfo(policyTypeSchema: PolicyTypeSchema): PolicyTypeInfo { - let info: PolicyTypeInfo = this.policyTypeInfo.get(policyTypeSchema.name); - if (!info) { - info = new PolicyTypeInfo(policyTypeSchema); - this.policyTypeInfo.set(policyTypeSchema.name, info); + deleteInstance(instance: PolicyInstance): void { + this.confirmDialogService + .openConfirmDialog( + "Are you sure you want to delete this policy instance?" + ) + .afterClosed() + .subscribe((res: any) => { + if (res) { + this.policySvc.deletePolicy(instance.policy_id).subscribe( + (response: HttpResponse) => { + switch (response.status) { + case 204: + this.notificationService.success("Delete succeeded!"); + this.getPolicyInstances(); + break; + default: + this.notificationService.warn( + "Delete failed " + response.status + " " + response.body + ); + } + }, + (error: HttpErrorResponse) => { + this.errorDialogService.displayError( + error.statusText + ", " + error.error + ); + } + ); } - return info; - } + }); + } - refreshTable() { - this.policyInstanceDataSource.getPolicyInstances(); + getPolicyTypeInfo(policyTypeSchema: PolicyTypeSchema): PolicyTypeInfo { + let info: PolicyTypeInfo = this.policyTypeInfo.get(policyTypeSchema.name); + if (!info) { + info = new PolicyTypeInfo(policyTypeSchema); + this.policyTypeInfo.set(policyTypeSchema.name, info); } + return info; + } + + refreshTable() { + this.getPolicyInstances(); + } +} + +function compare(a: string, b: string, isAsc: boolean) { + return (a < b ? -1 : 1) * (isAsc ? 1 : -1); } diff --git a/webapp-frontend/src/app/policy/policy-instance/policy-instance.datasource.ts b/webapp-frontend/src/app/policy/policy-instance/policy-instance.datasource.ts deleted file mode 100644 index 225aabb..0000000 --- a/webapp-frontend/src/app/policy/policy-instance/policy-instance.datasource.ts +++ /dev/null @@ -1,103 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * O-RAN-SC - * %% - * Copyright (C) 2019 Nordix Foundation - * %% - * 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. - * ========================LICENSE_END=================================== - */ - -import { DataSource } from '@angular/cdk/collections'; -import { MatSort } from '@angular/material/sort'; -import { Observable } from 'rxjs/Observable'; -import { BehaviorSubject } from 'rxjs/BehaviorSubject'; -import { merge } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { PolicyInstance } from '@interfaces/policy.types'; -import { PolicyService } from '@services/policy/policy.service'; -import { NotificationService } from '@services/ui/notification.service'; - -export class PolicyInstanceDataSource extends DataSource { - - policyInstances: PolicyInstance[] = []; - - private policyInstanceSubject = new BehaviorSubject([]); - - private loadingSubject = new BehaviorSubject(false); - - public loading$ = this.loadingSubject.asObservable(); - - public rowCount = 1; // hide footer during intial load - - constructor( - private policySvc: PolicyService, - public sort: MatSort, - private notificationService: NotificationService, - private policyTypeSchemaId: string) { - super(); - } - - public getPolicyInstances() { - this.policyInstances = [] as PolicyInstance[]; - this.policySvc.getPolicyInstancesByType(this.policyTypeSchemaId).subscribe(policies => { - if (policies.policy_ids.length != 0) { - policies.policy_ids.forEach(policyId => { - this.policySvc.getPolicyInstance(policyId).subscribe(policyInstance => { - this.policySvc.getPolicyStatus(policyId).subscribe(policyStatus => { - policyInstance.lastModified = policyStatus.last_modified; - }) - this.policyInstances.push(policyInstance); - }) - this.policyInstanceSubject.next(this.policyInstances); - }) - } - }) - } - - connect(): Observable { - const dataMutations = [ - this.policyInstanceSubject.asObservable(), - this.sort.sortChange - ]; - return merge(...dataMutations).pipe(map(() => { - return this.getSortedData([...this.policyInstanceSubject.getValue()]); - })); - } - - disconnect(): void { - this.policyInstanceSubject.complete(); - this.loadingSubject.complete(); - } - - private getSortedData(data: PolicyInstance[]) { - if (!this.sort || !this.sort.active || this.sort.direction === '') { - return data; - } - - return data.sort((a, b) => { - const isAsc = this.sort.direction === 'asc'; - switch (this.sort.active) { - case 'instanceId': return compare(a.policy_id, b.policy_id, isAsc); - case 'ric': return compare(a.ric_id, b.ric_id, isAsc); - case 'service': return compare(a.service_id, b.service_id, isAsc); - case 'lastModified': return compare(a.lastModified, b.lastModified, isAsc); - default: return 0; - } - }); - } -} - -function compare(a: string, b: string, isAsc: boolean) { - return (a < b ? -1 : 1) * (isAsc ? 1 : -1); -}