free text filter in instantiationStatus Page 02/99002/8
authorEylon Malin <eylon.malin@intl.att.com>
Tue, 3 Dec 2019 10:12:38 +0000 (12:12 +0200)
committerEylon Malin <eylon.malin@intl.att.com>
Tue, 3 Dec 2019 12:38:23 +0000 (14:38 +0200)
Issue-ID: VID-724
Change-Id: I5f363ecc66ff1f1fef9c9d75a12a9c43403aa905
Signed-off-by: Eylon Malin <eylon.malin@intl.att.com>
15 files changed:
vid-app-common/src/main/java/org/onap/vid/properties/Features.java
vid-webpack-master/cypress/integration/iFrames/instantiationStatus.e2e.ts
vid-webpack-master/cypress/support/jsonBuilders/mocks/jsons/flags.cypress.json
vid-webpack-master/cypress/support/steps/login.step.ts
vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.html
vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.scss
vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.spec.ts
vid-webpack-master/src/app/instantiationStatus/instantiationStatus.component.ts
vid-webpack-master/src/app/shared/components/genericFormPopup/genericFormServices/basic.popup.service.spec.ts
vid-webpack-master/src/app/shared/components/genericFormPopup/genericFormServices/network/network.popup.service.spec.ts
vid-webpack-master/src/app/shared/components/genericFormPopup/genericFormServices/vnf/vnf.popup.service.spec.ts
vid-webpack-master/src/app/shared/pipes/searchFilter/search-filter.pipe.spec.ts [new file with mode: 0644]
vid-webpack-master/src/app/shared/pipes/searchFilter/search-filter.pipe.ts [new file with mode: 0644]
vid-webpack-master/src/app/shared/services/featureFlag/feature-flags.service.ts
vid-webpack-master/src/app/shared/shared.module.ts

index 5da6465..0a78c34 100644 (file)
@@ -79,6 +79,7 @@ public enum Features implements Feature {
     FLAG_2002_VNF_PLATFORM_MULTI_SELECT,
     FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS,
     FLAG_2002_IDENTIFY_INVARIANT_MACRO_UUID_BY_BACKEND,
+    FLAG_2004_INSTANTIATION_STATUS_FILTER,
     ;
 
 
index 3b65734..054f785 100644 (file)
@@ -58,6 +58,18 @@ describe('Instantiation status', function () {
     }
   });
 
+  it('should filter rows by filter text', function () {
+    cy.openIframe('app/ui/#/instantiationStatus');
+    cy.getElementByDataTestsId("instantiationStatusFilter").type("ComplexService");
+    cy.get('table#instantiation-status tbody tr').should('have.length', 3);
+  });
+
+  it('should filter rows by url filter text', function () {
+    cy.openIframe('app/ui/#/instantiationStatus?filterText=ComplexService');
+    cy.getElementByDataTestsId("instantiationStatusFilter").should('have.value','ComplexService');
+    cy.get('table#instantiation-status tbody tr').should('have.length', 3);
+  });
+
   it('should enable correct menu items', function () {
         cy.openIframe('app/ui/#/instantiationStatus');
 
index 85e0917..b829361 100644 (file)
@@ -18,5 +18,6 @@
   "FLAG_1911_INSTANTIATION_ORDER_IN_ASYNC_ALACARTE": false,
   "FLAG_1911_INSTANTIATION_ORDER_BUTTON_IN_ASYNC_ALACARTE": false,
   "FLAG_2002_VNF_PLATFORM_MULTI_SELECT" : false,
-  "FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS": true
+  "FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS": true,
+  "FLAG_2004_INSTANTIATION_STATUS_FILTER": true
 }
index a7ed075..99c80bc 100644 (file)
@@ -34,8 +34,8 @@ function login(): void {
   }
 }
 
-function openIframe(iframeUrl : string): void {
-  cy.visit(iframeUrl);
+function openIframe(iframeUrl : string): Chainable<Window> {
+  return cy.visit(iframeUrl);
 }
 
 Cypress.Commands.add('login', login);
index 212981a..9ef98e5 100644 (file)
             <span class="icon-refresh"></span>
           </div>
         </div>
+        <div class="instantiationStatusFilter" *ngIf=isInstantiationStatusFilterFlagOn()>
+          <input
+            [attr.data-tests-id]="'instantiationStatusFilter'"
+            class="form-control input-text"
+            [placeholder]="'filter'"
+            [(ngModel)]="filterText">
+        </div>
       </div>
     </div>
   </div>
       </tr>
       </thead>
       <tbody >
-        <tr *ngFor="let data of serviceInfoData; trackBy: trackByFn; let i = index" [ngClass]="{'odd' : data.serviceIndex%2 == 1}" [id]="data.jobId">
-          <td class="smallTd" id="userId"><custom-ellipsis [id]="data.userId" [value]="data.userId"></custom-ellipsis></td>
-          <td class="smallTd" id="action"><custom-ellipsis [id]="data.action" [value]="data.action | capitalizeAndFormat"></custom-ellipsis></td>
-          <td class="normal" id="serviceModelName"><custom-ellipsis [id]="data.serviceModelName" [value]="data.serviceModelName"></custom-ellipsis></td>
-          <td class="normal" id="serviceInstanceName"><custom-ellipsis [id]="data.serviceInstanceName" [value]="data.serviceInstanceName"></custom-ellipsis></td>
-          <td class="smallTd" id="serviceModelVersion"><custom-ellipsis [id]="data.serviceModelVersion" [value]="data.serviceModelVersion"></custom-ellipsis></td>
-          <td class="normal" id="subscriberName"><custom-ellipsis [id]="data.subscriberName" [value]="data.subscriberName"></custom-ellipsis></td>
-          <td class="mediumTd" id="serviceType"><custom-ellipsis [id]="data.serviceType" [value]="data.serviceType"></custom-ellipsis></td>
-          <td class="normal" id="regionId"><custom-ellipsis [id]="data.regionId" [value]="data.regionId"></custom-ellipsis></td>
-          <td class="mediumTd" id="tenantName"><custom-ellipsis [id]="data.tenantName" [value]="data.tenantName"></custom-ellipsis></td>
-          <td class="mediumTd" id="aicZoneName"><custom-ellipsis [id]="data.aicZoneName" [value]="data.aicZoneName"></custom-ellipsis></td>
-          <td class="mediumTd" id="project"><custom-ellipsis [id]="data.project" [value]="data.project"></custom-ellipsis></td>
-          <td class="mediumTd" id="owningEntityName"><custom-ellipsis [id]="data.owningEntityName" [value]="data.owningEntityName"></custom-ellipsis></td>
-          <td class="smallTd" id="pause"><custom-ellipsis [id]="data.pause" [value]="data.pause"></custom-ellipsis></td>
-          <td class="mediumTd" id="created"><custom-ellipsis [id]="data.created" [value]="data.created | date:'MMM. dd, yyyy HH:mm'"></custom-ellipsis></td>
-          <td class="last" id="jobStatus" [ngClass]="data.jobStatus">
-            <custom-popover [value]="data.serviceStatus.tooltip"  [popoverType]="data?.serviceStatus?.color" style="float: left;">
-              <svg-icon
-                id="jobStatusIcon-{{i}}"
-                (click)="auditInfo(data)"
-                [mode]="data.serviceStatus.color"
-                [size]="'large'"
-                [name]="data.serviceStatus.iconClassName">
-              </svg-icon>
+      <tr *ngFor="let data of serviceInfoData | searchFilter: filterText ; trackBy: trackByFn; let i = index" [ngClass]="{'odd' : data.serviceIndex%2 == 1}" [id]="data.jobId">
+        <td class="smallTd" id="userId"><custom-ellipsis [id]="data.userId" [value]="data.userId"></custom-ellipsis></td>
+        <td class="smallTd" id="action"><custom-ellipsis [id]="data.action" [value]="data.action | capitalizeAndFormat"></custom-ellipsis></td>
+        <td class="normal" id="serviceModelName"><custom-ellipsis [id]="data.serviceModelName" [value]="data.serviceModelName"></custom-ellipsis></td>
+        <td class="normal" id="serviceInstanceName"><custom-ellipsis [id]="data.serviceInstanceName" [value]="data.serviceInstanceName"></custom-ellipsis></td>
+        <td class="smallTd" id="serviceModelVersion"><custom-ellipsis [id]="data.serviceModelVersion" [value]="data.serviceModelVersion"></custom-ellipsis></td>
+        <td class="normal" id="subscriberName"><custom-ellipsis [id]="data.subscriberName" [value]="data.subscriberName"></custom-ellipsis></td>
+        <td class="mediumTd" id="serviceType"><custom-ellipsis [id]="data.serviceType" [value]="data.serviceType"></custom-ellipsis></td>
+        <td class="normal" id="regionId"><custom-ellipsis [id]="data.regionId" [value]="data.regionId"></custom-ellipsis></td>
+        <td class="mediumTd" id="tenantName"><custom-ellipsis [id]="data.tenantName" [value]="data.tenantName"></custom-ellipsis></td>
+        <td class="mediumTd" id="aicZoneName"><custom-ellipsis [id]="data.aicZoneName" [value]="data.aicZoneName"></custom-ellipsis></td>
+        <td class="mediumTd" id="project"><custom-ellipsis [id]="data.project" [value]="data.project"></custom-ellipsis></td>
+        <td class="mediumTd" id="owningEntityName"><custom-ellipsis [id]="data.owningEntityName" [value]="data.owningEntityName"></custom-ellipsis></td>
+        <td class="smallTd" id="pause"><custom-ellipsis [id]="data.pause" [value]="data.pause"></custom-ellipsis></td>
+        <td class="mediumTd" id="created"><custom-ellipsis [id]="data.created" [value]="data.created | date:'MMM. dd, yyyy HH:mm'"></custom-ellipsis></td>
+        <td class="last" id="jobStatus" [ngClass]="data.jobStatus">
+          <custom-popover [value]="data.serviceStatus.tooltip"  [popoverType]="data?.serviceStatus?.color" style="float: left;">
+            <svg-icon
+              id="jobStatusIcon-{{i}}"
+              (click)="auditInfo(data)"
+              [mode]="data.serviceStatus.color"
+              [size]="'large'"
+              [name]="data.serviceStatus.iconClassName">
+            </svg-icon>
 
-            </custom-popover>
-            <div class="menu-div" (click)="onContextMenu($event, data)">
-                <span class="icon-menu"></span>
-                <context-menu>
-                  <ng-template *ngFor="let action of contextMenuActions" contextMenuItem let-item
-                               [visible]="action.visible"
-                               [enabled]="action.enabled"
-                               (execute)="action.click($event.item)">
-                    <div [attr.data-tests-id]="action.dataTestId"
-                         [tooltip]="action?.tooltip"
-                         [tooltipDisabled]="!action.tooltip">
+          </custom-popover>
+          <div class="menu-div" (click)="onContextMenu($event, data)">
+            <span class="icon-menu"></span>
+            <context-menu>
+              <ng-template *ngFor="let action of contextMenuActions" contextMenuItem let-item
+                           [visible]="action.visible"
+                           [enabled]="action.enabled"
+                           (execute)="action.click($event.item)">
+                <div [attr.data-tests-id]="action.dataTestId"
+                     [tooltip]="action?.tooltip"
+                     [tooltipDisabled]="!action.tooltip">
                       <span class="context-menu-icon">
                         <i class="fa {{action.className}}" aria-hidden="true"></i>
                       </span>
-                      {{action.name}}
-                    </div>
-                  </ng-template>
-              </context-menu>
-            </div>
-          </td>
+                  {{action.name}}
+                </div>
+              </ng-template>
+            </context-menu>
+          </div>
+        </td>
       </tr>
       </tbody>
     </table>
index 53dfcc1..e6ccdda 100644 (file)
@@ -17,7 +17,10 @@ import {FeatureFlagsService} from "../shared/services/featureFlag/feature-flags.
 import {JobStatus, ServiceAction} from "../shared/models/serviceInstanceActions";
 import each from 'jest-each';
 import {ServiceInfoModel} from "../shared/server/serviceInfo/serviceInfo.model";
-import { TooltipModule } from 'ngx-tooltip';
+import {TooltipModule} from 'ngx-tooltip';
+import {SearchFilterPipe} from "../shared/pipes/searchFilter/search-filter.pipe";
+import {ActivatedRoute} from "@angular/router";
+import {FormsModule} from "@angular/forms";
 
 class MockAppStore<T> {
 
@@ -36,10 +39,21 @@ class MockAppStore<T> {
   }
 }
 
+class ActivatedRouteMock<T>{
+  queryParams() {
+    return {}
+  };
+
+  snapshot = {
+    queryParams : {}
+  }
+}
+
 describe('Instantiation Status Component', () => {
   let component: InstantiationStatusComponent;
   let fixture: ComponentFixture<InstantiationStatusComponent>;
-let item = new ServiceInfoModel();
+  let item = new ServiceInfoModel();
+
   beforeAll(done => (async () => {
 
     TestBed.configureTestingModule({
@@ -48,7 +62,8 @@ let item = new ServiceInfoModel();
         ContextMenuModule,
         ScrollToModule.forRoot(),
         RouterTestingModule,
-        TooltipModule
+        TooltipModule,
+        FormsModule,
       ],
       providers: [
         ServiceInfoService,
@@ -59,9 +74,10 @@ let item = new ServiceInfoModel();
         FeatureFlagsService,
         ConfigurationService,
         LogService,
+        {provide: ActivatedRoute, useClass: ActivatedRouteMock},
         {provide: NgRedux, useClass: MockAppStore}
       ],
-      declarations: [InstantiationStatusComponent, CapitalizeAndFormatPipe],
+      declarations: [InstantiationStatusComponent, CapitalizeAndFormatPipe, SearchFilterPipe],
       schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
     });
     await TestBed.compileComponents();
index efb1a56..ba26716 100644 (file)
@@ -1,4 +1,4 @@
-import {Component, ViewChild} from '@angular/core';
+import {Component, OnInit, ViewChild} from '@angular/core';
 import {ServiceInfoService} from '../shared/server/serviceInfo/serviceInfo.service';
 import {ServiceInfoModel} from '../shared/server/serviceInfo/serviceInfo.model';
 import {InstantiationStatusComponentService} from './instantiationStatus.component.service';
@@ -11,6 +11,8 @@ import {LogService} from '../shared/utils/log/log.service';
 import {AppState} from "../shared/store/reducers";
 import {NgRedux} from '@angular-redux/store';
 import {JobStatus, ServiceAction} from "../shared/models/serviceInstanceActions";
+import {ActivatedRoute} from "@angular/router";
+import {FeatureFlagsService, Features} from "../shared/services/featureFlag/feature-flags.service";
 
 export interface MenuAction{
   name: string;
@@ -27,7 +29,7 @@ export interface MenuAction{
   templateUrl : './instantiationStatus.component.html',
   styleUrls : ['./instantiationStatus.component.scss']
 })
-export class InstantiationStatusComponent {
+export class InstantiationStatusComponent implements OnInit {
 
   TIMER_TIME_IN_SECONDS : number = 0;
   timer = null;
@@ -84,12 +86,14 @@ export class InstantiationStatusComponent {
   ];
 
   flags: any;
+  filterText: string;
   constructor(private _serviceInfoService: ServiceInfoService,
               private _instantiationStatusComponentService : InstantiationStatusComponentService,
               private _contextMenuService: ContextMenuService,
               private _configurationService : ConfigurationService,
               private _scrollToService: ScrollToService,
               private _logService : LogService,
+              private route: ActivatedRoute,
               private _store: NgRedux<AppState>) {
     this.instantiationStatusComponentService = _instantiationStatusComponentService;
     this.configurationService = this._configurationService;
@@ -100,6 +104,11 @@ export class InstantiationStatusComponent {
     });
   }
 
+  ngOnInit() {
+    let filterTextParam =  this.route.snapshot.queryParams["filterText"];
+    this.filterText = filterTextParam ? filterTextParam : "" ;
+  }
+
   activateInterval() {
     if (this.TIMER_TIME_IN_SECONDS > 0) {
       this.timer = setInterval(() => {
@@ -229,4 +238,8 @@ export class InstantiationStatusComponent {
       }, 0)
     }
   }
+
+  isInstantiationStatusFilterFlagOn() {
+    return FeatureFlagsService.getFlagState(Features.FLAG_2004_INSTANTIATION_STATUS_FILTER, this._store);
+  }
 }
index f5e07e7..a3c8326 100644 (file)
@@ -33,7 +33,6 @@ class MockReduxStore<T> {
           "FLAG_SHOW_VERIFY_SERVICE": false,
           "FLAG_SERVICE_MODEL_CACHE": true,
           "FLAG_ADVANCED_PORTS_FILTER": true,
-          MERGE_OBJECT_BY_PATH
           "FLAG_REGION_ID_FROM_REMOTE": true,
           "FLAG_ADD_MSO_TESTAPI_FIELD": true
         },
index 2a0a4c4..67c3712 100644 (file)
@@ -30,7 +30,6 @@ class MockReduxStore<T> {
           "FLAG_SHOW_VERIFY_SERVICE": false,
           "FLAG_SERVICE_MODEL_CACHE": true,
           "FLAG_ADVANCED_PORTS_FILTER": true,
-          MERGE_OBJECT_BY_PATH
           "FLAG_REGION_ID_FROM_REMOTE": true,
           "FLAG_ADD_MSO_TESTAPI_FIELD": true
         },
index 8c90655..2f19044 100644 (file)
@@ -30,7 +30,6 @@ class MockReduxStore<T> {
           "FLAG_SHOW_VERIFY_SERVICE": false,
           "FLAG_SERVICE_MODEL_CACHE": true,
           "FLAG_ADVANCED_PORTS_FILTER": true,
-          MERGE_OBJECT_BY_PATH
           "FLAG_REGION_ID_FROM_REMOTE": true,
           "FLAG_ADD_MSO_TESTAPI_FIELD": true
         },
diff --git a/vid-webpack-master/src/app/shared/pipes/searchFilter/search-filter.pipe.spec.ts b/vid-webpack-master/src/app/shared/pipes/searchFilter/search-filter.pipe.spec.ts
new file mode 100644 (file)
index 0000000..cbf7324
--- /dev/null
@@ -0,0 +1,17 @@
+import {SearchFilterPipe} from "./search-filter.pipe";
+import * as _ from 'lodash';
+
+describe('Search filter pipe', () => {
+
+  const items= [{'id':1, 'name': 'aaa'},
+    {'id':12, 'name': 'bbb', 'children':{'first': 155, 'second': 2, 'third': 3}},
+    {'id':3, 'name': 'ccc', 'children':{'first': 1, 'BbB': '3', 'third': 3}},
+    {'id':4, 'name': 'aad', 'children':{'first': 1, 'second': 2, 'third': 3}}];
+
+  test('should return items contains substring bb', () => {
+    let filter = new SearchFilterPipe();
+    let res:any[] = filter.transform(items,'bb');
+    expect(_.map(res, 'name' )).toEqual(['bbb','ccc']);
+  });
+
+});
diff --git a/vid-webpack-master/src/app/shared/pipes/searchFilter/search-filter.pipe.ts b/vid-webpack-master/src/app/shared/pipes/searchFilter/search-filter.pipe.ts
new file mode 100644 (file)
index 0000000..725eacb
--- /dev/null
@@ -0,0 +1,14 @@
+import {Pipe, PipeTransform} from '@angular/core';
+
+@Pipe({
+  name: 'searchFilter'
+})
+export class SearchFilterPipe implements PipeTransform {
+  transform(items: Object[], searchText: string): any[] {
+    if(!items) return [];
+    if(!searchText) return items;
+    return items.filter( item => {
+      return JSON.stringify(item).toLowerCase().includes(searchText.toLowerCase());
+    });
+  }
+}
index 518830d..2fb39e8 100644 (file)
@@ -13,6 +13,7 @@ export enum Features {
   FLAG_FLASH_REPLACE_VF_MODULE ='FLAG_FLASH_REPLACE_VF_MODULE',
   FLAG_FLASH_MORE_ACTIONS_BUTTON_IN_OLD_VIEW_EDIT ='FLAG_FLASH_MORE_ACTIONS_BUTTON_IN_OLD_VIEW_EDIT',
   FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS ='FLAG_2002_VFM_UPGRADE_ADDITIONAL_OPTIONS',
+  FLAG_2004_INSTANTIATION_STATUS_FILTER ='FLAG_2004_INSTANTIATION_STATUS_FILTER',
 }
 
 @Injectable()
index d246771..b12ac43 100644 (file)
@@ -74,6 +74,7 @@ import {DynamicInputsComponent} from "./components/dynamic-inputs/dynamic-inputs
 import {DynamicInputLabelPipe} from "./pipes/dynamicInputLabel/dynamic-input-label.pipe";
 import {ModelInformationService} from "./components/model-information/model-information.service";
 import {MultiselectFormControlService} from "./components/formControls/component/multiselect/multiselect.formControl.service";
+import {SearchFilterPipe} from "./pipes/searchFilter/search-filter.pipe";
 
 
 @NgModule({
@@ -114,6 +115,7 @@ import {MultiselectFormControlService} from "./components/formControls/component
     SafePipe,
     ObjectToArrayPipe,
     DataFilterPipe,
+    SearchFilterPipe,
     InputFormControlComponent,
     FormControlMessageErrorComponent,
     GenericFormPopupComponent,
@@ -145,6 +147,7 @@ import {MultiselectFormControlService} from "./components/formControls/component
     SafePipe,
     ObjectToArrayPipe,
     DataFilterPipe,
+    SearchFilterPipe,
     InputFormControlComponent,
     FormControlMessageErrorComponent,
     GenericFormPopupComponent,
@@ -196,6 +199,7 @@ import {MultiselectFormControlService} from "./components/formControls/component
     ElementsTableService,
     ErrorMsgService,
     DataFilterPipe,
+    SearchFilterPipe,
     ModelInformationService,
     MultiselectFormControlService
   ]