Feature 11011: Multiple NS deletion in OSM 16/14416/1
authorSANDHYA.JS <sandhya.j@tataelxsi.co.in>
Mon, 10 Jun 2024 12:53:41 +0000 (18:23 +0530)
committerSANDHYA.JS <sandhya.j@tataelxsi.co.in>
Mon, 10 Jun 2024 12:53:41 +0000 (18:23 +0530)
- Added multi option in smart table
- Added new terminate api for multi select deletion

Change-Id: Ia03d24e30c1c0a549ac1eda87264d58ab6d3bccd
Signed-off-by: SANDHYA.JS <sandhya.j@tataelxsi.co.in>
12 files changed:
src/app/instances/ns-instances/NSInstancesComponent.html
src/app/instances/ns-instances/NSInstancesComponent.ts
src/app/utilities/delete/DeleteComponent.html
src/app/utilities/delete/DeleteComponent.ts
src/app/utilities/ns-instances-action/NSInstancesActionComponent.ts
src/assets/i18n/de.json
src/assets/i18n/en.json
src/assets/i18n/es.json
src/assets/i18n/pt.json
src/environments/environment.prod.ts
src/environments/environment.ts
src/models/CommonModel.ts

index 8ee93b8..2f01b87 100644 (file)
@@ -18,6 +18,10 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
 <div class="d-flex flex-row justify-content-between">
     <div class="d-flex align-items-center header-style">{{'NSINSTANCES' | translate}}</div>
     <span class="button">
+        <button *ngIf="selectList?.length !== 0" class="btn btn-primary me-2" type="button" placement="top" container="body" ngbTooltip="{{'DELETENS' | translate}}"
+            (click)="deleteNS()">
+            <i class="fa fa-trash-alt" aria-hidden="true"></i>&nbsp; {{'DELETENS' | translate}}
+        </button>
         <button class="btn btn-primary me-2" type="button" placement="top" container="body" ngbTooltip="{{'PAGE.NSINSTANCE.NEWNSINSTANCE' | translate}}"
             (click)="instantiateNS()">
             <i class="fa fa-paper-plane" aria-hidden="true"></i>&nbsp; {{'PAGE.NSINSTANCE.NEWNSINSTANCE' | translate}}
@@ -39,7 +43,7 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
     <page-reload></page-reload>
 </div>
 <div class="smarttable-style bg-white mt-1">
-    <ng2-smart-table [ngClass]="checkDataClass" [settings]="settings" [source]="dataSource"
+    <ng2-smart-table #table [ngClass]="checkDataClass" [settings]="settings" [source]="dataSource"
         (userRowSelect)="onUserRowSelect($event)">
     </ng2-smart-table>
 </div>
index 14d6349..34719f3 100644 (file)
 /**
  * @file NS Instance Component
  */
-import { Component, Injector, OnInit } from '@angular/core';
+import { Component, Injector, OnInit, ViewChild } from '@angular/core';
 import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { TranslateService } from '@ngx-translate/core';
 import { CONFIGCONSTANT, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
 import { DataService } from 'DataService';
+import { DeleteComponent } from 'DeleteComponent';
 import { environment } from 'environment';
 import { InstantiateNsComponent } from 'InstantiateNs';
-import { LocalDataSource } from 'ng2-smart-table';
+import { LocalDataSource, Ng2SmartTableComponent } from 'ng2-smart-table';
 import { NSDInstanceData, NSInstanceDetails } from 'NSInstanceModel';
 import { NSInstancesActionComponent } from 'NSInstancesActionComponent';
 import { RestService } from 'RestService';
 import { Subscription } from 'rxjs';
+import { isNullOrUndefined } from 'SharedService';
 import { SharedService } from 'SharedService';
 
 /**
@@ -42,6 +44,8 @@ import { SharedService } from 'SharedService';
 })
 /** Exporting a class @exports NSInstancesComponent */
 export class NSInstancesComponent implements OnInit {
+    @ViewChild('table') table: Ng2SmartTableComponent;
+
     /** Injector to invoke other services @public */
     public injector: Injector;
 
@@ -52,10 +56,11 @@ export class NSInstancesComponent implements OnInit {
     public dataSource: LocalDataSource = new LocalDataSource();
 
     /** SelectedRows array @public */
-    public selectedRows: object[] = [];
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    public selectedRows: any;
 
     /** Selected list array @public */
-    public selectList: object[] = [];
+    public selectList: [] = [];
 
     /** Instance component are stored in settings @public */
     public settings: {} = {};
@@ -136,6 +141,7 @@ export class NSInstancesComponent implements OnInit {
     /** Generate smart table row title and filters @public  */
     public generateTableSettings(): void {
         this.settings = {
+            selectMode: 'multi',
             columns: this.columnList,
             actions: { add: false, edit: false, delete: false, position: 'right' },
             attr: this.sharedService.tableClassConfig(),
@@ -172,25 +178,25 @@ export class NSInstancesComponent implements OnInit {
                 valuePrepareFunction: (cell: NSDInstanceData, row: NSDInstanceData): string => {
                     if (row.OperationalStatus === this.operationalStateFirstStep) {
                         return `<span class="icon-label" title="${row.OperationalStatus}">
-                         <i class="fas fa-clock text-warning"></i>
-                         </span>`;
+                           <i class="fas fa-clock text-warning"></i>
+                           </span>`;
                     } else if (row.OperationalStatus === this.operationalStateSecondStep) {
                         return `<span class="icon-label" title="${row.OperationalStatus}">
-                         <i class="fas fa-check-circle text-success"></i>
-                         </span>`;
+                           <i class="fas fa-check-circle text-success"></i>
+                           </span>`;
                     } else if (row.OperationalStatus === this.operationalStateThirdStep) {
                         return `<span class="icon-label" title="${row.OperationalStatus}">
-                         <i class="fas fa-times-circle text-danger"></i>
-                         </span>`;
+                           <i class="fas fa-times-circle text-danger"></i>
+                           </span>`;
                     } else if (row.OperationalStatus === this.operationalStateFourthStep) {
                         return `<span class="icon-label" title="${row.OperationalStatus}">
-                         <i class="fas fa-compress-alt text-success"></i>
-                         </span>`;
+                           <i class="fas fa-compress-alt text-success"></i>
+                           </span>`;
                     }
                     else if (row.OperationalStatus === this.operationalStateFifthStep) {
                         return `<span class="icon-label" title="${row.OperationalStatus}">
-                         <i class="fas fa-briefcase-medical text-success"></i>
-                         </span>`;
+                           <i class="fas fa-briefcase-medical text-success"></i>
+                           </span>`;
                     } else {
                         return `<span>${row.OperationalStatus}</span>`;
                     }
@@ -212,16 +218,16 @@ export class NSInstancesComponent implements OnInit {
                 valuePrepareFunction: (cell: NSDInstanceData, row: NSDInstanceData): string => {
                     if (row.ConfigStatus === this.configStateFirstStep) {
                         return `<span class="icon-label" title="${row.ConfigStatus}">
-                         <i class="fas fa-clock text-warning"></i>
-                         </span>`;
+                           <i class="fas fa-clock text-warning"></i>
+                           </span>`;
                     } else if (row.ConfigStatus === this.configStateSecondStep) {
                         return `<span class="icon-label" title="${row.ConfigStatus}">
-                         <i class="fas fa-check-circle text-success"></i>
-                         </span>`;
+                           <i class="fas fa-check-circle text-success"></i>
+                           </span>`;
                     } else if (row.ConfigStatus === this.configStateThirdStep) {
                         return `<span class="icon-label" title="${row.ConfigStatus}">
-                         <i class="fas fa-times-circle text-danger"></i>
-                         </span>`;
+                           <i class="fas fa-times-circle text-danger"></i>
+                           </span>`;
                     } else {
                         return `<span>${row.ConfigStatus}</span>`;
                     }
@@ -285,14 +291,46 @@ export class NSInstancesComponent implements OnInit {
 
     /** smart table listing manipulation @public */
     public onUserRowSelect(event: MessageEvent): void {
-        Object.assign(event.data, { page: 'ns-instance' });
-        this.dataService.changeMessage(event.data);
+        if (!isNullOrUndefined(event)) {
+            this.selectedRows = event;
+            if (this.selectedRows.selected.length !== 0) {
+                this.selectList = this.selectedRows.selected;
+            } else {
+                if (!isNullOrUndefined(event.data)) {
+                    Object.assign(event.data, { page: 'ns-instance' });
+                    this.dataService.changeMessage(event.data);
+                }
+                this.selectList.length = 0;
+            }
+        }
+    }
+
+    /** delete NS using modalservice @public */
+    public deleteNS(): void {
+        // eslint-disable-next-line security/detect-non-literal-fs-filename
+        const modalRef: NgbModalRef = this.modalService.open(DeleteComponent, { backdrop: 'static' });
+        modalRef.componentInstance.params = {
+            identifierList: this.selectList,
+            page: 'instantiateNS'
+        };
+        modalRef.result.then((result: MODALCLOSERESPONSEDATA) => {
+            if (result) {
+                this.sharedService.callData();
+                this.table.isAllSelected = false;
+                this.selectList.length = 0;
+            }
+        }).catch((): void => {
+            // Catch Navigation Error
+        });
     }
 
     /** Instantiate NS using modalservice @public */
     public instantiateNS(): void {
         // eslint-disable-next-line security/detect-non-literal-fs-filename
         const modalRef: NgbModalRef = this.modalService.open(InstantiateNsComponent, { backdrop: 'static' });
+        modalRef.componentInstance.params = {
+            titleName: 'instantiateNS'
+        };
         modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
             if (result) {
                 this.generateData();
index a39cb61..513bc21 100644 (file)
@@ -28,6 +28,9 @@ Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.i
 </div>
 <div class="modal-footer">
   <button (click)="activeModal.close()" class="btn btn-danger">{{'CANCEL' | translate}}</button>
-  <button (click)="deleteData();" class="btn btn-primary">{{'OK' | translate }}</button>
+  <button *ngIf="!isPage; else multiDelete" (click)="deleteData();" class="btn btn-primary">{{'OK' | translate}}</button>
+  <ng-template #multiDelete>
+    <button *ngIf="isPage" (click)="terminate();" class="btn btn-primary">{{'DELETE' | translate }}</button>
+  </ng-template>
 </div>
 <app-loader [waitingMessage]="message" *ngIf="isLoadingResults"></app-loader>
\ No newline at end of file
index b403e9b..d79d4e4 100644 (file)
@@ -23,10 +23,11 @@ import { Component, Injector, Input } from '@angular/core';
 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { TranslateService } from '@ngx-translate/core';
 import { NotifierService } from 'angular-notifier';
-import { DELETEPARAMS, ERRORDATA, MODALCLOSERESPONSEDATA, URLPARAMS } from 'CommonModel';
+import { APIURLHEADER, DELETEPARAMS, ERRORDATA, MODALCLOSERESPONSEDATA, URLPARAMS } from 'CommonModel';
 import { DataService } from 'DataService';
 import { environment } from 'environment';
 import { RestService } from 'RestService';
+import { isNullOrUndefined } from 'SharedService';
 
 /**
  * Creating component
@@ -54,6 +55,13 @@ export class DeleteComponent {
   /** Check the loading results @public */
   public isLoadingResults: Boolean = false;
 
+  /** Check the page @public */
+  public isPage: Boolean = false;
+
+  /** Number of instances @public */
+  // eslint-disable-next-line @typescript-eslint/no-magic-numbers
+  public noOfInstances: Number = 25;
+
   /** Give the message for the loading @public */
   public notifyMessage: string = 'DELETELOADERMESSAGE';
 
@@ -106,8 +114,20 @@ export class DeleteComponent {
       if (data.identifier !== undefined || data.identifier !== '' || data.identifier !== null) {
         this.id = data.identifier;
       }
-      this.createTitleandID(data);
-      this.createDeleteUrl(data);
+      if (!isNullOrUndefined(this.params)) {
+        if (this.params.page === 'instantiateNS') {
+          this.isPage = true;
+          this.title = '';
+          this.createDeleteUrl(data);
+        } else if (this.params.page === 'ns-instance') {
+          this.createDeleteUrl(data);
+          this.isPage = false;
+        }
+      } else {
+        this.createTitleandID(data);
+        this.createDeleteUrl(data);
+        this.isPage = false;
+      }
     });
   }
   /** Generate Title and Id from data @public */
@@ -129,10 +149,18 @@ export class DeleteComponent {
   /** Generate Delete url from data @public */
   public createDeleteUrl(data: DELETEPARAMS): void {
     this.deleteURL = '';
-    if (data.page === 'ns-instance') {
-      this.deleteURL = environment.NSINSTANCESCONTENT_URL;
-      this.forceDelete = this.params.forceDeleteType;
-    } else if (data.page === 'ns-package') {
+    if (!isNullOrUndefined(this.params)) {
+      if (this.params.page === 'ns-instance') {
+        this.deleteURL = environment.NSINSTANCESCONTENT_URL;
+        this.forceDelete = this.params.forceDeleteType;
+        this.title = this.params.name;
+        this.id = this.params.id;
+      } else if (this.params.page === 'instantiateNS') {
+        this.deleteURL = environment.NSINSTANCESTERMINATE_URL;
+        this.notifyMessage = 'DELETEDSUCCESSFULLY';
+      }
+    }
+    if (data.page === 'ns-package') {
       this.deleteURL = environment.NSDESCRIPTORSCONTENT_URL;
       this.notifyMessage = 'DELETEDSUCCESSFULLY';
     } else if (data.page === 'vnf-package') {
@@ -191,7 +219,7 @@ export class DeleteComponent {
     }
     this.restService.deleteResource(deletingURl).subscribe((res: {}) => {
       this.activeModal.close(modalData);
-      this.notifierService.notify('success', this.translateService.instant(this.notifyMessage, { title: this.title}));
+      this.notifierService.notify('success', this.translateService.instant(this.notifyMessage, { title: this.title }));
     }, (error: ERRORDATA) => {
       this.isLoadingResults = false;
       this.restService.handleError(error, 'delete');
@@ -199,4 +227,41 @@ export class DeleteComponent {
       this.isLoadingResults = false;
     });
   }
+
+  /** terminate multiple ns instances function @public */
+  public terminate(): void {
+    this.isLoadingResults = true;
+    const modalData: MODALCLOSERESPONSEDATA = {
+      message: 'Done'
+    };
+    const idData: string[] = [];
+    this.params.identifierList.forEach((data: DELETEPARAMS) => {
+      idData.push(data.identifier);
+    });
+    if (idData.length > this.noOfInstances) {
+      this.activeModal.close(modalData);
+      this.notifierService.notify('warning', this.translateService.instant('WARNINGMESSAGE'));
+    } else {
+      const postData: {} = {
+        ns_ids: idData
+      };
+      let deletingURl: string = '';
+      deletingURl = this.deleteURL;
+      this.notifyMessage = 'DELETELOADMESSAGE';
+      const apiURLHeader: APIURLHEADER = {
+        url: deletingURl,
+        httpOptions: { headers: this.headers }
+      };
+      this.restService.postResource(apiURLHeader, postData).subscribe(() => {
+        this.activeModal.close(modalData);
+        this.isLoadingResults = false;
+        this.notifierService.notify('success', this.translateService.instant(this.notifyMessage));
+      }, (error: ERRORDATA) => {
+        this.isLoadingResults = false;
+        this.restService.handleError(error, 'post');
+      }, () => {
+        this.isLoadingResults = false;
+      });
+    }
+  }
 }
index 1582bc4..61f6d16 100644 (file)
@@ -163,7 +163,12 @@ export class NSInstancesActionComponent {
   public deleteNSInstance(forceAction: boolean): void {
     // eslint-disable-next-line security/detect-non-literal-fs-filename
     const modalRef: NgbModalRef = this.modalService.open(DeleteComponent, { backdrop: 'static' });
-    modalRef.componentInstance.params = { forceDeleteType: forceAction };
+    modalRef.componentInstance.params = {
+      forceDeleteType: forceAction,
+      name: this.value.name,
+      page: 'ns-instance',
+      id: this.instanceID
+    };
     modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
       if (result) {
         this.sharedService.callData();
index dd6e156..30340a5 100644 (file)
@@ -92,6 +92,9 @@
     "SESSIONEXPIRY": "Sitzung abgelaufen, bitte erneut anmelden",
     "DELETECONFIRMPOPUPMESSAGE": "Möchten Sie wirklich löschen?",
     "DELETELOADERMESSAGE": "Bitte warten Sie, während der Löschvorgang ausgeführt wird",
+    "DELETELOADMESSAGE": "Bitte warten Sie, während der Löschvorgang ausgeführt wird",
+    "WARNINGMESSAGE": "Es können nicht mehr als 25 Instanzen gelöscht werden",
+    "DELETENS":"NS löschen",
     "VALUE": "Wert",
     "PERFORMACTION": "Aktion ausführen",
     "EXECUTE": "Execute",
index ebe8d7c..b18a013 100644 (file)
@@ -92,6 +92,9 @@
     "SESSIONEXPIRY": "Session expired, please login again",
     "DELETECONFIRMPOPUPMESSAGE": "Are you sure want to delete",
     "DELETELOADERMESSAGE": "Please wait while {{title}} deletion is in progress",
+    "DELETELOADMESSAGE": "Please wait while deletion is in progress",
+    "WARNINGMESSAGE": "Cannot delete more than 25 instances",
+    "DELETENS":"Delete NS",
     "VALUE": "Value",
     "PERFORMACTION": "Perform Action",
     "EXECUTE": "Execute",
index 354058b..29b9044 100644 (file)
@@ -92,6 +92,9 @@
     "SESSIONEXPIRY": "Sesión expirada, por favor ingrese de nuevo",
     "DELETECONFIRMPOPUPMESSAGE": "¿Seguro que lo quiere eliminar?",
     "DELETELOADERMESSAGE": "Por favor, espere mientras la eliminación está en progreso",
+    "DELETELOADMESSAGE": "Por favor, espere mientras la eliminación está en progreso",
+    "WARNINGMESSAGE": "No se pueden eliminar más de 25 instancias",
+    "DELETENS":"Eliminar NS",
     "VALUE": "Valor",
     "PERFORMACTION": "Realizar una acción",
     "EXECUTE": "Ejecutar",
index 98b3c46..4508b5a 100644 (file)
@@ -92,6 +92,9 @@
     "SESSIONEXPIRY": "Sessão expirada, faça o login novamente",
     "DELETECONFIRMPOPUPMESSAGE": "Tem certeza de que deseja excluir",
     "DELETELOADERMESSAGE": "Aguarde enquanto a exclusão está em andamento",
+    "DELETELOADMESSAGE": "Aguarde enquanto a exclusão está em andamento",
+    "WARNINGMESSAGE": "Não é possível excluir mais de 25 instâncias",
+    "DELETENS":"Excluir NS",
     "VALUE": "Valor",
     "PERFORMACTION": "Executar a ação",
     "EXECUTE": "Executar",
index 9ab1c1f..b3b625d 100644 (file)
@@ -66,6 +66,7 @@ export const environment = {
     NSDINSTANCES_URL: OSM_NSLCM_ENDPOINT + 'ns_instances',
     VNFINSTANCES_URL: OSM_NSLCM_ENDPOINT + 'vnfrs',
     NSINSTANCESCONTENT_URL: OSM_NSLCM_ENDPOINT + 'ns_instances_content',
+    NSINSTANCESTERMINATE_URL: OSM_NSLCM_ENDPOINT + 'ns_instances_terminate',
     NSHISTORYOPERATIONS_URL: OSM_NSLCM_ENDPOINT + 'ns_lcm_op_occs',
     NETWORKSLICEINSTANCESCONTENT_URL: OSM_NSILCM_ENDPOINT + 'netslice_instances_content',
     NSTHISTORYOPERATIONS_URL: OSM_NSILCM_ENDPOINT + '/nsi_lcm_op_occs',
index bd45964..3f80777 100644 (file)
@@ -66,6 +66,7 @@ export const environment = {
     NSDINSTANCES_URL: OSM_NSLCM_ENDPOINT + 'ns_instances',
     VNFINSTANCES_URL: OSM_NSLCM_ENDPOINT + 'vnfrs',
     NSINSTANCESCONTENT_URL: OSM_NSLCM_ENDPOINT + 'ns_instances_content',
+    NSINSTANCESTERMINATE_URL: OSM_NSLCM_ENDPOINT + 'ns_instances_terminate',
     NSHISTORYOPERATIONS_URL: OSM_NSLCM_ENDPOINT + 'ns_lcm_op_occs',
     NETWORKSLICEINSTANCESCONTENT_URL: OSM_NSILCM_ENDPOINT + 'netslice_instances_content',
     NSTHISTORYOPERATIONS_URL: OSM_NSILCM_ENDPOINT + 'nsi_lcm_op_occs',
index a3038f1..581bbfb 100644 (file)
@@ -128,6 +128,7 @@ export interface URLPARAMS {
     configs?: object;
     actions?: object;
     executedActions?: EXECUTEDACTIONS[];
+    identifierList: [];
 }
 /** Handle the Delete params */
 export interface DELETEPARAMS {