From cde4ceece9e916ef9387e78982df21b13dc58837 Mon Sep 17 00:00:00 2001 From: maximesson Date: Mon, 11 Jan 2021 10:53:10 +0100 Subject: [PATCH 1/1] Filtering the producer in the frontend Change-Id: Ib7c1aacccd01e610a7d3f7bb445d60b46b7e1abc Issue-ID: NONRTRIC-338 Signed-off-by: maximesson --- .../portal/nonrtric/controlpanel/RestApiTest.java | 28 ++++++- .../EnrichmentControllerMockConfiguration.java | 9 ++ webapp-backend/src/test/resources/job-2.json | 5 ++ webapp-frontend/package.json | 2 +- .../ei-coordinator/ei-coordinator.component.html | 95 ++++++++++++---------- .../ei-coordinator/ei-coordinator.component.scss | 14 ++++ .../app/ei-coordinator/ei-coordinator.component.ts | 41 ++++++++-- .../src/app/ei-coordinator/ei-job.datasource.ts | 10 +-- .../app/ei-coordinator/ei-producer.datasource.ts | 14 +++- webapp-frontend/src/app/interfaces/ei.jobs.ts | 8 -- webapp-frontend/src/app/mock/ei-jobs.json | 10 +++ webapp-frontend/src/app/mock/ei-producers.json | 14 ++++ webapp-frontend/src/app/services/ei/ei.service.ts | 1 - 13 files changed, 176 insertions(+), 75 deletions(-) create mode 100644 webapp-backend/src/test/resources/job-2.json diff --git a/webapp-backend/src/test/java/org/oransc/portal/nonrtric/controlpanel/RestApiTest.java b/webapp-backend/src/test/java/org/oransc/portal/nonrtric/controlpanel/RestApiTest.java index 5a0cd71..5309d98 100644 --- a/webapp-backend/src/test/java/org/oransc/portal/nonrtric/controlpanel/RestApiTest.java +++ b/webapp-backend/src/test/java/org/oransc/portal/nonrtric/controlpanel/RestApiTest.java @@ -94,8 +94,16 @@ class RestApiTest { .targetUri("http://example.com/") // .owner("owner") // .build(); - assertThat(jobs).hasSize(1) // - .contains(gson.toJsonTree(wantedJobInfo)); + JobInfo wantedJobInfo2 = JobInfo.builder() // + .id("job2") // + .typeId("type2") // + .jobData(getStringFromFile("job-2.json")) // + .targetUri("http://example.com/") // + .owner("owner") // + .build(); + assertThat(jobs).hasSize(6) // + .contains(gson.toJsonTree(wantedJobInfo), // + gson.toJsonTree(wantedJobInfo2)); } @Test @@ -111,8 +119,20 @@ class RestApiTest { .types(new String[] {"type1", "type2"}) // .status("ENABLED") // .build(); - assertThat(producers).hasSize(1) // - .contains(gson.toJsonTree(wantedProducerInfo)); + ProducerInfo wantedProducerInfo2 = ProducerInfo.builder() // + .id("prod-2") // + .types(new String[] {"type1"}) // + .status("DISABLED") // + .build(); + ProducerInfo wantedProducerInfo3 = ProducerInfo.builder() // + .id("3-prod") // + .types(new String[] {"type1", "type2"}) // + .status("ENABLED") // + .build(); + assertThat(producers).hasSize(3) // + .contains(gson.toJsonTree(wantedProducerInfo), // + gson.toJsonTree(wantedProducerInfo2), // + gson.toJsonTree(wantedProducerInfo3)); } private AsyncRestClient restClient() { diff --git a/webapp-backend/src/test/java/org/oransc/portal/nonrtric/controlpanel/mock/EnrichmentControllerMockConfiguration.java b/webapp-backend/src/test/java/org/oransc/portal/nonrtric/controlpanel/mock/EnrichmentControllerMockConfiguration.java index b9dcc6b..b8d75c3 100644 --- a/webapp-backend/src/test/java/org/oransc/portal/nonrtric/controlpanel/mock/EnrichmentControllerMockConfiguration.java +++ b/webapp-backend/src/test/java/org/oransc/portal/nonrtric/controlpanel/mock/EnrichmentControllerMockConfiguration.java @@ -123,9 +123,18 @@ public class EnrichmentControllerMockConfiguration { putEiProducerInstance("prod-1", "http://example.com/", "http://example.com/", "http://example.com/", supported_types, new ProducerStatusInfo(ProducerStatusInfo.OperationalState.ENABLED)); + putEiProducerInstance("prod-2", "http://example.com/", "http://example.com/", "http://example.com/", + Arrays.asList(supported_types.get(0)), new ProducerStatusInfo(ProducerStatusInfo.OperationalState.DISABLED)); + + putEiProducerInstance("3-prod", "http://example.com/", "http://example.com/", "http://example.com/", + supported_types, new ProducerStatusInfo(ProducerStatusInfo.OperationalState.ENABLED)); + // Create EiJob instance schema = getStringFromFile("job-1.json"); putEiJobInstance("type1", "job1", schema, "owner", "http://example.com/"); + + schema = getStringFromFile("job-1.json"); + putEiJobInstance("type2", "job2", schema, "owner", "http://example.com/"); } private String getStringFromFile(String path) { diff --git a/webapp-backend/src/test/resources/job-2.json b/webapp-backend/src/test/resources/job-2.json new file mode 100644 index 0000000..3f9e757 --- /dev/null +++ b/webapp-backend/src/test/resources/job-2.json @@ -0,0 +1,5 @@ +{ + "jobparam1":"value1", + "jobparam2":"value2", + "jobparam3":"value3" +} diff --git a/webapp-frontend/package.json b/webapp-frontend/package.json index 95ff727..ee07def 100644 --- a/webapp-frontend/package.json +++ b/webapp-frontend/package.json @@ -17,7 +17,6 @@ "@angular/common": "^8.2.14", "@angular/flex-layout": "^7.0.0-beta.24", "@angular/forms": "^8.2.14", - "@angular/material": "~7.2.0", "@angular/platform-browser": "^8.2.14", "@angular/platform-browser-dynamic": "^8.2.14", "@angular/router": "^8.2.14", @@ -50,6 +49,7 @@ "@angular/compiler-cli": "^8.2.14", "@angular/core": "^8.2.14", "@angular/language-service": "^8.2.14", + "@angular/material": "^7.2.2", "@nguniversal/express-engine": "^8.2.6", "@types/jasmine": "^2.8.16", "@types/jasminewd2": "^2.0.8", diff --git a/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.html b/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.html index 30f1eee..9e99cf0 100644 --- a/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.html +++ b/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.html @@ -29,48 +29,59 @@ limitations under the License.

Producers

- - - - - - - - - - - - - - - -
Producer ID {{this.getEIProducerId(eiProducer)}} Producer type {{this.getEIProducerTypes(eiProducer)}} Producer status {{this.getEIProducerStatus(eiProducer)}}
+
+ +
+
+ + + + + + + + + + + +
Producer IDProducer typeProducer status
+ {{eiProducer.ei_producer_id}} + + {{this.getEIProducerTypes(eiProducer)}} + + {{this.getEIProducerStatus(eiProducer)}} +
+

Jobs

- - - - - - - - - - - - - - - - - - - - -
Job ID {{this.getDisplayName(eiJob)}} Type ID {{this.getEITypeId(eiJob)}} Owner {{eiJob.owner}} Target URI {{this.getTargetUri(eiJob)}}
\ No newline at end of file +
+ + + + + + + + + + + + + + + + + + + +
Job ID {{this.getDisplayName(eiJob)}} Type ID {{this.getEITypeId(eiJob)}} Owner {{eiJob.owner}} Target URI {{this.getTargetUri(eiJob)}}
+
\ No newline at end of file diff --git a/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.scss b/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.scss index 5038944..759f2a8 100644 --- a/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.scss +++ b/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.scss @@ -35,6 +35,10 @@ background-color: transparent; } +.table-dark { + background-color: #2d2d3d; +} + .action-cell { display: flex; justify-content: flex-end; @@ -48,4 +52,14 @@ display: flex; justify-content: space-between; flex-wrap: wrap; +} + +.table-container { + margin-top: 10px; + max-height: 300px; + overflow: auto; +} + +.filter-form { + width: 200px; } \ No newline at end of file diff --git a/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.ts b/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.ts index c76bd89..7c4979e 100644 --- a/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.ts +++ b/webapp-frontend/src/app/ei-coordinator/ei-coordinator.component.ts @@ -17,17 +17,20 @@ * limitations under the License. * ========================LICENSE_END=================================== */ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, Version } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatSort } from '@angular/material/sort'; import { animate, state, style, transition, trigger } from '@angular/animations'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { MatTableDataSource } from '@angular/material'; import { EIService } from '../services/ei/ei.service'; import { EIJob, EIProducer } from '../interfaces/ei.jobs'; import { EIProducerDataSource } from './ei-producer.datasource'; import { EIJobDataSource } from './ei-job.datasource'; import { NotificationService } from '../services/ui/notification.service'; -import { BehaviorSubject, Observable } from 'rxjs'; +import { defer, BehaviorSubject, Observable } from 'rxjs'; +import { map, withLatestFrom, startWith, tap } from 'rxjs/operators'; import { UiService } from '../services/ui/ui.service'; class EIJobInfo { @@ -51,34 +54,54 @@ class EIJobInfo { }) export class EICoordinatorComponent implements OnInit { - eiJobsDataSource: EIJobDataSource; eiProducersDataSource: EIProducerDataSource; + producers$: Observable; + filteredProducers$: Observable; @ViewChild(MatSort, { static: true }) sort: MatSort; eiJobInfo = new Map(); darkMode: boolean; + searchString: string; + formGroup: FormGroup; + eiProducersData: MatTableDataSource; + constructor( private eiSvc: EIService, private dialog: MatDialog, private notificationService: NotificationService, - private ui: UiService) { } + private ui: UiService, + private formBuilder: FormBuilder) { + this.formGroup = formBuilder.group({ filter: [""] }); + } ngOnInit() { this.eiJobsDataSource = new EIJobDataSource(this.eiSvc, this.sort, this.notificationService); this.eiProducersDataSource = new EIProducerDataSource(this.eiSvc, this.sort, this.notificationService); this.eiJobsDataSource.loadTable(); - this.eiProducersDataSource.loadTable(); + //this.eiProducersDataSource.loadTable(); + + this.producers$= this.eiProducersDataSource.getProducers(); + this.filteredProducers$ = defer(() => this.formGroup.get("filter") + .valueChanges.pipe( + startWith(""), + withLatestFrom(this.producers$), + map(([val, producers]) => + !val ? producers : producers.filter((x) => + x.ei_producer_id.toLowerCase().includes(val)))) + ); + this.ui.darkModeState.subscribe((isDark) => { this.darkMode = isDark; }); } - toggleListInstances(eiJob: EIJob): void { - const info = this.getEIJobInfo(eiJob); - info.isExpanded.next(!info.isExpanded.getValue()); - } + ngAfterViewInit() { + this.eiJobsDataSource.sort = this.sort; + this.eiProducersDataSource.sort = this.sort; + + } getEIJobInfo(eiJob: EIJob): EIJobInfo { let info: EIJobInfo = this.eiJobInfo.get(eiJob.ei_job_data); diff --git a/webapp-frontend/src/app/ei-coordinator/ei-job.datasource.ts b/webapp-frontend/src/app/ei-coordinator/ei-job.datasource.ts index a8a786f..b0a348a 100644 --- a/webapp-frontend/src/app/ei-coordinator/ei-job.datasource.ts +++ b/webapp-frontend/src/app/ei-coordinator/ei-job.datasource.ts @@ -58,7 +58,6 @@ export class EIJobDataSource extends DataSource { finalize(() => this.loadingSubject.next(false)) ) .subscribe((instances: EIJob[]) => { - console.log("Jobs: " + instances); this.rowCount = instances.length; this.eiJobSubject.next(instances); }); @@ -87,12 +86,9 @@ export class EIJobDataSource extends DataSource { return data.sort((a, b) => { const isAsc = this.sort.direction === 'asc'; switch (this.sort.active) { - case 'id': return compare(a.ei_job_identity, b.ei_job_identity, isAsc); - //case 'eiTypeId': return compare(a.eiTypeId, b.eiTypeId, isAsc); - //case 'jobResultUri': return compare(a.jobResultUri, b.jobResultUri, isAsc); - //case 'jobOwner': return compare(a.jobOwner, b.jobOwner, isAsc); - //case 'jobStatusNotificationUri': return compare(a.jobStatusNotificationUri, b.jobStatusNotificationUri, isAsc); - //case 'jobDefinition': return compare(a.jobDefinition, b.jobDefinition, isAsc); + case 'ei_job_identity': return compare(a.ei_job_identity, b.ei_job_identity, isAsc); + case 'owner': return compare(a.owner, b.owner, isAsc); + case 'ei_type_identity': return compare(a.ei_type_identity, b.ei_type_identity, isAsc); default: return 0; } }); diff --git a/webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.ts b/webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.ts index 866d785..44af50a 100644 --- a/webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.ts +++ b/webapp-frontend/src/app/ei-coordinator/ei-producer.datasource.ts @@ -18,14 +18,14 @@ * ========================LICENSE_END=================================== */ -import { DataSource } from '@angular/cdk/collections'; +import { CollectionViewer, DataSource } from '@angular/cdk/collections'; import { HttpErrorResponse } from '@angular/common/http'; import { MatSort } from '@angular/material'; import { Observable } from 'rxjs/Observable'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { merge } from 'rxjs'; import { of } from 'rxjs/observable/of'; -import { catchError, finalize, map } from 'rxjs/operators'; +import { catchError, finalize, map, tap } from 'rxjs/operators'; import { EIProducer } from '../interfaces/ei.jobs'; import { EIService } from '../services/ei/ei.service'; import { NotificationService } from '../services/ui/notification.service'; @@ -62,6 +62,7 @@ export class EIProducerDataSource extends DataSource { this.rowCount = prods.length; this.producerSubject.next(prods); }); + this.connect(); } connect(): Observable { @@ -87,11 +88,18 @@ export class EIProducerDataSource extends DataSource { return data.sort((a, b) => { const isAsc = this.sort.direction === 'asc'; switch (this.sort.active) { - case 'ei_producer_id': return compare(a.ei_producer_id, b.ei_producer_id, isAsc); + case 'id': return compare(a.ei_producer_id, b.ei_producer_id, isAsc); + case 'type': return compare(a.ei_producer_types[0], b.ei_producer_types[0], isAsc); + case 'status': return compare(a.status, b.status, isAsc); default: return 0; } }); } + + getProducers(): Observable { + return this.eiSvc.getEIProducers() + .pipe(tap(console.log)); + } } function compare(a: string, b: string, isAsc: boolean) { diff --git a/webapp-frontend/src/app/interfaces/ei.jobs.ts b/webapp-frontend/src/app/interfaces/ei.jobs.ts index 4ead13f..29c2a8b 100644 --- a/webapp-frontend/src/app/interfaces/ei.jobs.ts +++ b/webapp-frontend/src/app/interfaces/ei.jobs.ts @@ -20,14 +20,6 @@ // Models of data used by the EI Coordinator -export interface EIJobBis { - eiTypeId: string; - jobResultUri: string; - jobOwner: string; - jobStatusNotificationUri: string; - jobDefinition: any; -} - export interface EIJob { ei_job_identity: string; ei_job_data: any; diff --git a/webapp-frontend/src/app/mock/ei-jobs.json b/webapp-frontend/src/app/mock/ei-jobs.json index 6d96872..79b4c44 100644 --- a/webapp-frontend/src/app/mock/ei-jobs.json +++ b/webapp-frontend/src/app/mock/ei-jobs.json @@ -9,5 +9,15 @@ "jobparam1": "value1_job1" }, "target_uri": "https://ricsim_g3_1:8185/datadelivery" + }, + { + "ei_job_identity": "job2", + "ei_type_identity": "type2", + "ei_job_data": { + "jobparam2": "value2_job2", + "jobparam3": "value3_job2", + "jobparam1": "value1_job2" + }, + "target_uri": "https://ricsim_g3_1:8185/datadelivery" } ] \ No newline at end of file diff --git a/webapp-frontend/src/app/mock/ei-producers.json b/webapp-frontend/src/app/mock/ei-producers.json index 75cedc5..2a2be7a 100644 --- a/webapp-frontend/src/app/mock/ei-producers.json +++ b/webapp-frontend/src/app/mock/ei-producers.json @@ -5,5 +5,19 @@ "type1" ], "status": "ENABLED" + }, + { + "ei_producer_id": "prod-2", + "ei_producer_types": [ + "type2" + ], + "status": "ENABLED" + }, + { + "ei_producer_id": "3-prod", + "ei_producer_types": [ + "type1" + ], + "status": "DISABLED" } ] \ No newline at end of file diff --git a/webapp-frontend/src/app/services/ei/ei.service.ts b/webapp-frontend/src/app/services/ei/ei.service.ts index cbc0a55..976b7b8 100644 --- a/webapp-frontend/src/app/services/ei/ei.service.ts +++ b/webapp-frontend/src/app/services/ei/ei.service.ts @@ -43,7 +43,6 @@ export class EIService { args.forEach(part => { result = result + '/' + part; }); - console.log("URL: "+result); return result; } -- 2.16.6