From 19570d54903b181469ee2806043d562dadc1d804 Mon Sep 17 00:00:00 2001 From: jh245g Date: Thu, 30 May 2019 13:32:08 -0400 Subject: [PATCH] add column sorting Issue-ID: RICPLT-1344 Signed-off-by: Jun (Nicolas) Hu Change-Id: Ia7be93ec29aff5ebdb7eaf992bab0ca0a8b860cc --- docs/release-notes.rst | 1 + .../src/app/catalog/catalog.component.html | 8 ++--- .../src/app/catalog/catalog.component.ts | 12 ++++--- .../src/app/catalog/catalog.datasource.ts | 39 ++++++++++++++++++--- .../src/app/control/control.component.html | 14 ++++---- .../src/app/control/control.component.ts | 13 +++---- .../src/app/control/control.datasource.ts | 40 +++++++++++++++++++--- 7 files changed, 95 insertions(+), 32 deletions(-) diff --git a/docs/release-notes.rst b/docs/release-notes.rst index e2f00c64..c50e4cc3 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -24,6 +24,7 @@ Version 1.0.4, 30 May 2019 -------------------------- * Add ANR xApp neighbor cell relation table * Drop the pendulum xApp control screen +* Add column sorting on xApp catalog and xApp control * Add disconnect-all button to RAN connection screen Version 1.0.3, 28 May 2019 diff --git a/webapp-frontend/src/app/catalog/catalog.component.html b/webapp-frontend/src/app/catalog/catalog.component.html index 2379fd43..2277bb7f 100644 --- a/webapp-frontend/src/app/catalog/catalog.component.html +++ b/webapp-frontend/src/app/catalog/catalog.component.html @@ -22,20 +22,20 @@
- +
- xApp Name + xApp Name {{element.name}} - xApp version + xApp version {{element.version}} - Status + Status {{element.status}} diff --git a/webapp-frontend/src/app/catalog/catalog.component.ts b/webapp-frontend/src/app/catalog/catalog.component.ts index 96e040e2..04b83805 100644 --- a/webapp-frontend/src/app/catalog/catalog.component.ts +++ b/webapp-frontend/src/app/catalog/catalog.component.ts @@ -17,11 +17,12 @@ * limitations under the License. * ========================LICENSE_END=================================== */ -import { Component, OnInit} from '@angular/core'; -import { XappMgrService } from '../services/xapp-mgr/xapp-mgr.service'; -import { ConfirmDialogService } from './../services/ui/confirm-dialog.service' -import { NotificationService } from './../services/ui/notification.service' +import { Component, OnInit, ViewChild } from '@angular/core'; +import { MatSort } from '@angular/material/sort'; import { ErrorDialogService } from '../services/ui/error-dialog.service'; +import { XappMgrService } from '../services/xapp-mgr/xapp-mgr.service'; +import { ConfirmDialogService } from './../services/ui/confirm-dialog.service'; +import { NotificationService } from './../services/ui/notification.service'; import { CatalogDataSource } from './catalog.datasource'; @Component({ @@ -33,6 +34,7 @@ export class CatalogComponent implements OnInit{ displayedColumns: string[] = ['name', 'version', 'status', 'action']; dataSource: CatalogDataSource; + @ViewChild(MatSort) sort: MatSort; constructor( private xappMgrSvc: XappMgrService, @@ -41,7 +43,7 @@ export class CatalogComponent implements OnInit{ private notification: NotificationService) { } ngOnInit() { - this.dataSource = new CatalogDataSource(this.xappMgrSvc); + this.dataSource = new CatalogDataSource(this.xappMgrSvc, this.sort ); this.dataSource.loadTable(); } diff --git a/webapp-frontend/src/app/catalog/catalog.datasource.ts b/webapp-frontend/src/app/catalog/catalog.datasource.ts index 6ee6e92f..f6ae32d4 100644 --- a/webapp-frontend/src/app/catalog/catalog.datasource.ts +++ b/webapp-frontend/src/app/catalog/catalog.datasource.ts @@ -19,12 +19,14 @@ */ import { CollectionViewer, DataSource } from '@angular/cdk/collections'; +import { MatSort } from '@angular/material'; +import { merge } from 'rxjs'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { Observable } from 'rxjs/Observable'; -import { catchError, finalize } from 'rxjs/operators'; import { of } from 'rxjs/observable/of'; -import { BehaviorSubject } from 'rxjs/BehaviorSubject'; -import { XappMgrService } from '../services/xapp-mgr/xapp-mgr.service'; +import { catchError, finalize, map } from 'rxjs/operators'; import { XMXapp } from '../interfaces/xapp-mgr.types'; +import { XappMgrService } from '../services/xapp-mgr/xapp-mgr.service'; export class CatalogDataSource extends DataSource { @@ -34,7 +36,7 @@ export class CatalogDataSource extends DataSource { public loading$ = this.loadingSubject.asObservable(); - constructor(private xappMgrSvc: XappMgrService) { + constructor(private xappMgrSvc: XappMgrService, private sort: MatSort ) { super(); }; @@ -49,11 +51,38 @@ export class CatalogDataSource extends DataSource { } connect(collectionViewer: CollectionViewer): Observable { - return this.xAppsSubject.asObservable(); + const dataMutations = [ + this.xAppsSubject.asObservable(), + this.sort.sortChange + ]; + return merge(...dataMutations).pipe(map(() => { + return this.getSortedData([...this.xAppsSubject.getValue()]); + })); } disconnect(collectionViewer: CollectionViewer): void { this.xAppsSubject.complete(); this.loadingSubject.complete(); } + + private getSortedData(data: XMXapp[]) { + if (!this.sort.active || this.sort.direction === '') { + return data; + } + + return data.sort((a, b) => { + const isAsc = this.sort.direction === 'asc'; + switch (this.sort.active) { + case 'name': return compare(a.name, b.name, isAsc); + case 'version': return compare(a.version, b.version, isAsc); + case 'status': return compare(a.status, b.status, isAsc); + default: return 0; + } + }); + } } + +function compare(a, b, isAsc) { + return (a < b ? -1 : 1) * (isAsc ? 1 : -1); +} + diff --git a/webapp-frontend/src/app/control/control.component.html b/webapp-frontend/src/app/control/control.component.html index 1e7bca2d..5ae35aa0 100644 --- a/webapp-frontend/src/app/control/control.component.html +++ b/webapp-frontend/src/app/control/control.component.html @@ -22,30 +22,30 @@
-
+
- xApp Name + xApp Name {{element.xapp}} - Instance Name + Instance Name {{element.instance.name}} - Status + Status {{element.instance.status}} - - IP + + IP {{element.instance.ip}} - Port + Port {{element.instance.port}} diff --git a/webapp-frontend/src/app/control/control.component.ts b/webapp-frontend/src/app/control/control.component.ts index 29a88ccf..755625c7 100644 --- a/webapp-frontend/src/app/control/control.component.ts +++ b/webapp-frontend/src/app/control/control.component.ts @@ -17,16 +17,16 @@ * limitations under the License. * ========================LICENSE_END=================================== */ -import { Component, OnInit } from '@angular/core'; -import { XappMgrService } from '../services/xapp-mgr/xapp-mgr.service'; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { MatSort } from '@angular/material/sort'; import { Router } from '@angular/router'; -import { ErrorDialogService } from './../services/ui/error-dialog.service'; +import { XappControlRow } from '../interfaces/xapp-mgr.types'; +import { XappMgrService } from '../services/xapp-mgr/xapp-mgr.service'; import { ConfirmDialogService } from './../services/ui/confirm-dialog.service'; +import { ErrorDialogService } from './../services/ui/error-dialog.service'; import { NotificationService } from './../services/ui/notification.service'; -import { XappControlRow } from '../interfaces/xapp-mgr.types'; import { ControlAnimations } from './control.animations'; import { ControlDataSource } from './control.datasource'; -import { routerNgProbeToken } from '@angular/router/src/router_module'; @Component({ selector: 'app-control', @@ -38,6 +38,7 @@ export class ControlComponent implements OnInit { displayedColumns: string[] = ['xapp', 'name', 'status', 'ip', 'port', 'action']; dataSource: ControlDataSource; + @ViewChild(MatSort) sort: MatSort; constructor( private xappMgrSvc: XappMgrService, @@ -47,7 +48,7 @@ export class ControlComponent implements OnInit { private notification: NotificationService) { } ngOnInit() { - this.dataSource = new ControlDataSource(this.xappMgrSvc); + this.dataSource = new ControlDataSource(this.xappMgrSvc, this.sort); this.dataSource.loadTable(); } diff --git a/webapp-frontend/src/app/control/control.datasource.ts b/webapp-frontend/src/app/control/control.datasource.ts index 833a4f06..30752efa 100644 --- a/webapp-frontend/src/app/control/control.datasource.ts +++ b/webapp-frontend/src/app/control/control.datasource.ts @@ -19,12 +19,14 @@ */ import { CollectionViewer, DataSource } from '@angular/cdk/collections'; +import { MatSort } from '@angular/material'; +import { merge } from 'rxjs'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { Observable } from 'rxjs/Observable'; -import { catchError, finalize } from 'rxjs/operators'; import { of } from 'rxjs/observable/of'; -import { BehaviorSubject } from 'rxjs/BehaviorSubject'; +import { catchError, finalize, map } from 'rxjs/operators'; +import { XappControlRow, XMXapp } from '../interfaces/xapp-mgr.types'; import { XappMgrService } from '../services/xapp-mgr/xapp-mgr.service'; -import { XMXapp, XappControlRow } from '../interfaces/xapp-mgr.types'; export class ControlDataSource extends DataSource { @@ -34,7 +36,7 @@ export class ControlDataSource extends DataSource { public loading$ = this.loadingSubject.asObservable(); - constructor(private xappMgrSvc: XappMgrService) { + constructor(private xappMgrSvc: XappMgrService, private sort: MatSort) { super(); }; @@ -49,7 +51,13 @@ export class ControlDataSource extends DataSource { } connect(collectionViewer: CollectionViewer): Observable { - return this.xAppInstancesSubject.asObservable(); + const dataMutations = [ + this.xAppInstancesSubject.asObservable(), + this.sort.sortChange + ]; + return merge(...dataMutations).pipe(map(() => { + return this.getSortedData([...this.xAppInstancesSubject.getValue()]); + })); } disconnect(collectionViewer: CollectionViewer): void { @@ -71,4 +79,26 @@ export class ControlDataSource extends DataSource { } return xAppInstances; } + + private getSortedData(data: XappControlRow[]) { + if (!this.sort.active || this.sort.direction === '') { + return data; + } + + return data.sort((a, b) => { + const isAsc = this.sort.direction === 'asc'; + switch (this.sort.active) { + case 'xapp': return compare(a.xapp, b.xapp, isAsc); + case 'name': return compare(a.instance.name, b.instance.name, isAsc); + case 'status': return compare(a.instance.status, b.instance.status, isAsc); + case 'ip': return compare(a.instance.ip, b.instance.ip, isAsc); + case 'port': return compare(a.instance.port, b.instance.port, isAsc); + default: return 0; + } + }); + } } + +function compare(a, b, isAsc) { + return (a < b ? -1 : 1) * (isAsc ? 1 : -1); +} \ No newline at end of file -- 2.16.6