Merge "Polling mechanism to get jobs"
[portal/nonrtric-controlpanel.git] / webapp-frontend / src / app / policy / policy-instance / policy-instance.component.ts
index 0f34c43..1649d39 100644 (file)
  * ========================LICENSE_END===================================
  */
 
-import { MatSort } 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 { Observable } from 'rxjs';
-import { UiService } from '../../services/ui/ui.service';
+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 { 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 { HttpResponse } from "@angular/common/http";
+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";
 
 @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;
+  darkMode: boolean;
+  instanceDataSource: MatTableDataSource<PolicyInstance>;
+  policyInstanceForm: FormGroup;
+  private policyInstanceSubject = new BehaviorSubject<PolicyInstance[]>([]);
+  policyInstances: PolicyInstance[] = [];
 
+  constructor(
+    private policySvc: PolicyService,
+    private dialog: MatDialog,
+    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 {
-    instanceDataSource: PolicyInstanceDataSource;
-    @Input() policyTypeSchema: PolicyTypeSchema;
-    @Input() expanded: Observable<boolean>;
-    @ViewChild(MatSort, { static: true }) sort: MatSort;
-    darkMode: boolean;
-
-    constructor(
-        private policySvc: PolicyService,
-        private dialog: MatDialog,
-        private errorDialogService: ErrorDialogService,
-        private notificationService: NotificationService,
-        private confirmDialogService: ConfirmDialogService,
-        private ui: UiService) {
-    }
-
-    ngOnInit() {
-        this.instanceDataSource = new PolicyInstanceDataSource(this.policySvc, this.sort, this.policyTypeSchema);
-        this.expanded.subscribe((isExpanded: boolean) => this.onExpand(isExpanded));
-        this.ui.darkModeState.subscribe((isDark) => {
-            this.darkMode = isDark;
+  ngOnInit() {
+    this.getPolicyInstances();
+    this.policyInstanceSubject.subscribe((data) => {
+      this.instanceDataSource = new MatTableDataSource<PolicyInstance>(data);
+
+      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.policyInstanceForm.valueChanges.subscribe((value) => {
+      const filter = {
+        ...value,
+        id: value.id.trim().toLowerCase(),
+      } as string;
+      this.instanceDataSource.filter = filter;
+    });
+
+    this.ui.darkModeState.subscribe((isDark) => {
+      this.darkMode = isDark;
+    });
+  }
+
+  getPolicyInstances() {
+    this.policyInstances = [] as PolicyInstance[];
+    this.policySvc
+      .getPolicyInstancesByType(this.policyTypeSchema.id)
+      .pipe(
+        mergeMap((policyIds) =>
+          forkJoin(
+            policyIds.policy_ids.map((id) => {
+              return forkJoin([
+                this.policySvc.getPolicyInstance(id),
+                this.policySvc.getPolicyStatus(id),
+              ]);
+            })
+          )
+        )
+      )
+      .subscribe((res) => {
+        this.policyInstances = res.map((policy) => {
+          let policyInstance = <PolicyInstance>{};
+          policyInstance = policy[0];
+          policyInstance.lastModified = policy[1].last_modified;
+          return policyInstance;
         });
-    }
+        this.policyInstanceSubject.next(this.policyInstances);
+      });
+  }
+
+  getSortedData(sort: Sort) {
+    const data = this.instanceDataSource.data;
+    data.sort((a: PolicyInstance, b: PolicyInstance) => {
+      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;
+  }
+
+  stopSort(event: any) {
+    event.stopPropagation();
+  }
+
+  isDataIncluding(data: string, filter: string): boolean {
+    return !filter || data.toLowerCase().includes(filter);
+  }
+
+  createPolicyInstance(policyTypeSchema: PolicyTypeSchema): void {
+    this.openInstanceDialog(null);
+  }
 
-    ngAfterViewInit() {
-        this.instanceDataSource.sort = this.sort;
-    }
+  modifyInstance(instance: PolicyInstance): void {
+    this.policySvc
+      .getPolicyInstance(instance.policy_id)
+      .subscribe((refreshedJson: PolicyInstance) => {
+        this.openInstanceDialog(refreshedJson);
+      });
+  }
 
-    private onExpand(isExpanded: boolean) {
-        if (isExpanded) {
-            this.instanceDataSource.getPolicyInstances();
+  private openInstanceDialog(policy: PolicyInstance) {
+    const dialogData = getPolicyDialogProperties(
+      this.policyTypeSchema,
+      policy,
+      this.darkMode
+    );
+    const dialogRef = this.dialog.open(
+      PolicyInstanceDialogComponent,
+      dialogData
+    );
+    dialogRef.afterClosed().subscribe((ok: any) => {
+      if (ok) this.getPolicyInstances();
+    });
+  }
+
+  hasInstances(): boolean {
+    return this.instanceCount() > 0;
+}
+
+  instanceCount(): number {
+    return this.policyInstances.length;
+  }
+
+  toLocalTime(utcTime: string): string {
+    const date = new Date(utcTime);
+    const toutc = date.toUTCString();
+    return new Date(toutc + " UTC").toLocaleString();
+  }
+
+  deleteInstance(instance: PolicyInstance): void {
+    this.confirmDialogService
+      .openConfirmDialog(
+        "Delete Policy",
+        "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<Object>) => {
+              if (response.status === 204) {
+                this.notificationService.success("Delete succeeded!");
+                this.getPolicyInstances();
+              }
+            });
         }
-    }
-
-    private isSchemaEmpty(): boolean {
-        return this.policyTypeSchema.schemaObject === '{}';
-    }
-
-    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.instanceDataSource.getPolicyInstances();
-                        }
-                    );
-            },
-            (httpError: HttpErrorResponse) => {
-                this.notificationService.error('Could not refresh instance. Please try again.' + httpError.message);
-            }
-        );
-    }
-
-    hasInstances(): boolean {
-        return this.instanceDataSource.rowCount > 0;
-    }
-
-    toLocalTime(utcTime: string): string {
-        const date = new Date(utcTime);
-        const toutc = date.toUTCString();
-        return new Date(toutc + ' UTC').toLocaleString();
-
-    }
-
-    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<Object>) => {
-                                    switch (response.status) {
-                                        case 204:
-                                            this.notificationService.success('Delete succeeded!');
-                                            this.instanceDataSource.getPolicyInstances();
-                                            break;
-                                        default:
-                                            this.notificationService.warn('Delete failed ' + response.status + ' ' + response.body);
-                                    }
-                                },
-                                (error: HttpErrorResponse) => {
-                                    this.errorDialogService.displayError(error.statusText + ', ' + error.error);
-                                });
-                    }
-                });
-    }
+      });
+  }
+
+  refreshTable() {
+    this.getPolicyInstances();
+  }
+}
+
+function compare(a: string, b: string, isAsc: boolean) {
+  return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
 }