import { MainComponent } from './main/main.component';
import { MaterialDesignFrameworkModule } from 'angular6-json-schema-form';
import { PolicyModule } from './policy/policy.module'
+import { EiCoordinatorModule } from './ei-coordinator/ei-coordinator.module'
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { SidenavListComponent } from './navigation/sidenav-list/sidenav-list.component';
import { CookieService } from 'ngx-cookie-service';
import { NodeModulesComponent } from './node-modules/node-modules.component';
import { EICardComponent } from './ui/ei-card/ei-card.component';
-import { EICoordinatorComponent } from './ei-coordinator/ei-coordinator.component';
import { HttpMockRequestInterceptor } from './interceptor.mock';
import { environment } from 'src/environments/environment';
import { HttpRequestInterceptor } from './interceptor';
-import { ProducersListComponent } from './ei-coordinator/producers-list/producers-list.component';
export const isMock = environment.mock;
AppComponent,
ConfirmDialogComponent,
EICardComponent,
- EICoordinatorComponent,
ErrorDialogComponent,
FooterComponent,
MainComponent,
NodeModulesComponent,
SidenavListComponent,
- ProducersListComponent,
],
imports: [
AppRoutingModule,
MaterialDesignFrameworkModule,
MDBBootstrapModule.forRoot(),
PolicyModule,
+ EiCoordinatorModule,
ReactiveFormsModule,
ToastrModule.forRoot(),
],
providers: [
CookieService,
ErrorDialogService,
- ProducersListComponent,
UiService,
{
provide: HTTP_INTERCEPTORS,
<div fxLayout="row">
<div class="nrcp-global-page-title">Enrichment Information Coordinator</div>
<div class="refresh-button">
- <button id="refreshButton" mat-icon-button color="primary" (click)="refreshTables()">
+ <button id="refreshButton" mat-icon-button color="primary" (click)="refreshTables()">
<mat-icon>refresh</mat-icon>
</button>
</div>
<br>
<h4>Producers</h4>
- <nrcp-producers-list></nrcp-producers-list>
+<nrcp-producers-list></nrcp-producers-list>
<br>
<h4>Jobs</h4>
-
-<div class="table-container">
- <mat-table id="jobsTable" [dataSource]="jobsDataSource" fixedLayout
- matSort (matSortChange)="sortJobs($event)"
- class="ei-coordinator-table mat-elevation-z8">
- <ng-container matColumnDef="id">
- <mat-header-cell *matHeaderCellDef mat-sort-header>
- <div (click)="stopSort($event)">
- <form style="display: flex" [formGroup]="jobsFormControl">
- <mat-form-field>
- <input id="jobIdFilter" matInput formControlName="id">
- <mat-placeholder>Job ID</mat-placeholder>
- </mat-form-field>
- </form>
- </div>
- </mat-header-cell>
- <mat-cell *matCellDef="let eiJob"> {{eiJob.ei_job_identity}} </mat-cell>
- </ng-container>
- <ng-container matColumnDef="typeId">
- <mat-header-cell *matHeaderCellDef mat-sort-header>
- <div (click)="stopSort($event)">
- <form style="display: flex" [formGroup]="jobsFormControl">
- <mat-form-field>
- <input id="jobTypeIdFilter" matInput formControlName="typeId">
- <mat-placeholder>Type ID</mat-placeholder>
- </mat-form-field>
- </form>
- </div>
- </mat-header-cell>
- <mat-cell *matCellDef="let eiJob">{{this.getJobTypeId(eiJob)}} </mat-cell>
- </ng-container>
- <ng-container matColumnDef="owner">
- <mat-header-cell *matHeaderCellDef mat-sort-header>
- <div (click)="stopSort($event)">
- <form style="display: flex" [formGroup]="jobsFormControl">
- <mat-form-field>
- <input id="jobOwnerFilter" matInput formControlName="owner">
- <mat-placeholder>Owner</mat-placeholder>
- </mat-form-field>
- </form>
- </div>
- </mat-header-cell>
- <mat-cell *matCellDef="let eiJob">{{this.getJobOwner(eiJob)}} </mat-cell>
- </ng-container>
- <ng-container matColumnDef="targetUri">
- <mat-header-cell *matHeaderCellDef mat-sort-header>
- <div (click)="stopSort($event)">
- <form style="display: flex" [formGroup]="jobsFormControl">
- <mat-form-field>
- <input id="jobTargetUriFilter" matInput formControlName="targetUri">
- <mat-placeholder>Target URI</mat-placeholder>
- </mat-form-field>
- </form>
- </div>
- </mat-header-cell>
- <mat-cell *matCellDef="let eiJob"> {{eiJob.target_uri}} </mat-cell>
- </ng-container>
- <mat-header-row *matHeaderRowDef="['id', 'typeId', 'owner', 'targetUri']"></mat-header-row>
- <mat-row *matRowDef="let row; columns: ['id', 'typeId', 'owner', 'targetUri'];"></mat-row>
- </mat-table>
-</div>
\ No newline at end of file
+<nrcp-jobs-list></nrcp-jobs-list>
\ No newline at end of file
* limitations under the License.
* ========================LICENSE_END===================================
*/
-
-.ei-coordinator-table {
- width: 100%;
- min-height: 150px;
- margin-top: 10px;
- margin-bottom: 10px;
- background-color: transparent;
-}
-
-.table-dark {
- background-color: #2d2d3d;
-}
-
.display-none {
display: none;
}
display: flex;
justify-content: space-between;
flex-wrap: wrap;
-}
-
-.table-container {
- margin-top: 10px;
- max-height: 300px;
- overflow: auto;
-}
-
-.filter-form {
- width: 200px;
-}
-
-.mat-form-field {
- font-size: 14px;
- width: 100%;
-}
+}
\ No newline at end of file
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
-import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
-import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
+import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { HarnessLoader } from '@angular/cdk/testing';
import { MatButtonModule } from '@angular/material/button';
import { MatButtonHarness } from '@angular/material/button/testing';
import { MatIconModule } from '@angular/material/icon';
-import { MatInputHarness } from '@angular/material/input/testing'
import { MatTableModule } from '@angular/material/table';
-import { MatTableHarness } from '@angular/material/table/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
-import { of } from 'rxjs';
import { EICoordinatorComponent } from './ei-coordinator.component';
-import { EIJobDataSource } from './ei-job.datasource';
import { UiService } from '../services/ui/ui.service';
-import { EIJob } from '../interfaces/ei.types';
import { ProducersListComponent } from './producers-list/producers-list.component';
+import { JobsListComponent } from './jobs-list/jobs-list.component';
describe('EICoordinatorComponent', () => {
let component: EICoordinatorComponent;
let fixture: ComponentFixture<EICoordinatorComponent>;
let loader: HarnessLoader;
- let producersListSpy: jasmine.SpyObj<ProducersListComponent>;
- let jobDataSourceSpy: jasmine.SpyObj<EIJobDataSource>;
-
- const job1 = {
- ei_job_identity: 'job1',
- ei_type_identity: 'type1',
- owner: 'owner1',
- target_uri: 'http://one'
- } as EIJob;
- const job2 = {
- ei_job_identity: 'job2',
- ei_type_identity: 'type2',
- owner: 'owner2',
- target_uri: 'http://two'
- } as EIJob;
beforeEach(async () => {
- producersListSpy = jasmine.createSpyObj('producersListSpy', ['refresh']);
- jobDataSourceSpy = jasmine.createSpyObj('EIJobDataSource', [ 'loadJobs', 'eiJobs', 'eiJobsSubject' ]);
-
- jobDataSourceSpy.eiJobsSubject.and.returnValue(of([ job1, job2 ]));
await TestBed.configureTestingModule({
imports: [
MatButtonModule,
MatIconModule,
MatTableModule,
- BrowserAnimationsModule,
- ReactiveFormsModule
+ BrowserAnimationsModule
],
schemas: [
CUSTOM_ELEMENTS_SCHEMA
],
declarations: [
- EICoordinatorComponent
+ EICoordinatorComponent,
+ JobsListStubComponent,
+ ProducerListStubComponent,
],
providers: [
- { provide: ProducersListComponent, useValue: producersListSpy },
- { provide: EIJobDataSource, useValue: jobDataSourceSpy },
- UiService,
- FormBuilder,
+ UiService
]
})
.compileComponents();
fixture = TestBed.createComponent(EICoordinatorComponent);
component = fixture.componentInstance;
+
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
});
describe('#content', () => {
- it('should contain refresh button with coorect icon', async () => {
+ it('should contain refresh button with correct icon', async () => {
let refreshButton = await loader.getHarness(MatButtonHarness.with({ selector: '#refreshButton' }));
expect(refreshButton).toBeTruthy();
expect(await refreshButton.getText()).toEqual('refresh');
expect(producersTableComponent).toBeTruthy();
});
- it('should contain jobs table with correct columns', async () => {
- let producersTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' }));
- let headerRow = (await producersTable.getHeaderRows())[0];
- let headers = await headerRow.getCellTextByColumnName();
-
- expect(headers).toEqual({ id: 'Job ID', typeId: 'Type ID', owner: 'Owner', targetUri: 'Target URI' });
+ it('should contain jobs table', async () => {
+ const jobsComponent = fixture.debugElement.nativeElement.querySelector('nrcp-jobs-list');
+ expect(jobsComponent).toBeTruthy();
});
it('should set correct dark mode from UIService', () => {
it('should refresh tables', async () => {
let refreshButton = await loader.getHarness(MatButtonHarness.with({ selector: '#refreshButton' }));
+ spyOn(component.producersList, 'refresh');
+ spyOn(component.jobComponent, 'refresh');
await refreshButton.click();
- expect(producersListSpy.refresh).toHaveBeenCalled();
+ expect(component.jobComponent.refresh).toHaveBeenCalled();
+ expect(component.producersList.refresh).toHaveBeenCalled();
});
});
- describe('#jobsTable', () => {
- const expectedJob1Row = { id: 'job1', typeId: 'type1', owner: 'owner1', targetUri: 'http://one' };
- beforeEach(() => {
- const jobs: EIJob[] = [ job1, job2 ];
- jobDataSourceSpy.eiJobsSubject.and.returnValue(of(jobs));
- });
-
- it('should contain data after initialization', async () => {
- component.ngOnInit();
- const expectedJobRows = [
- expectedJob1Row,
- { id: 'job2', typeId: 'type2', owner: 'owner2', targetUri: 'http://two' }
- ];
- let jobsTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' }));
- let jobRows = await jobsTable.getRows();
- expect(jobRows.length).toEqual(2);
- jobRows.forEach(row => {
- row.getCellTextByColumnName().then(values => {
- expect(expectedJobRows).toContain(jasmine.objectContaining(values));
- });
- });
- });
-
- it('job defaults', async () => {
- const jobMissingProperties = {
- ei_job_identity: 'job1',
- target_uri: 'http://one'
- } as EIJob;
- const jobs: EIJob[] = [jobMissingProperties];
- jobDataSourceSpy.eiJobsSubject.and.returnValue(of(jobs));
- component.ngOnInit();
-
- const expectedJobRow = { id: 'job1', typeId: '< No type >', owner: '< No owner >', targetUri: 'http://one' };
- let jobsTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' }));
- let jobRows = await jobsTable.getRows();
- expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJobRow);
- });
+ @Component({
+ selector: 'nrcp-jobs-list',
+ template: '',
+ providers: [
+ {
+ provide: JobsListComponent,
+ useClass: JobsListStubComponent
+ }
+ ]
+ })
+ class JobsListStubComponent {
+ refresh() { }
+ }
+
+ @Component({
+ selector: 'nrcp-producers-list',
+ template: '',
+ providers: [
+ {
+ provide: ProducersListComponent,
+ useClass: ProducerListStubComponent
+ }
+ ]
+ })
+ class ProducerListStubComponent {
+ refresh() { }
+ }
- it('filtering', async () => {
- component.ngOnInit();
- let jobsTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' }));
-
- let idFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobIdFilter' }));
- await idFilterInput.setValue("1");
- let jobRows = await jobsTable.getRows();
- expect(jobRows.length).toEqual(1);
- expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJob1Row);
-
- idFilterInput.setValue('');
- let typeIdFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobTypeIdFilter' }));
- await typeIdFilterInput.setValue("1");
- jobRows = await jobsTable.getRows();
- expect(jobRows.length).toEqual(1);
-
- typeIdFilterInput.setValue('');
- let ownerFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobOwnerFilter' }));
- await ownerFilterInput.setValue("1");
- jobRows = await jobsTable.getRows();
- expect(jobRows.length).toEqual(1);
- expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJob1Row);
-
- ownerFilterInput.setValue('');
- let targetUriFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobTargetUriFilter' }));
- await targetUriFilterInput.setValue("one");
- jobRows = await jobsTable.getRows();
- expect(jobRows.length).toEqual(1);
- expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJob1Row);
- });
- });
});
* limitations under the License.
* ========================LICENSE_END===================================
*/
-import { Component, OnInit } from '@angular/core';
-import { Sort } from '@angular/material/sort';
-import { FormBuilder, FormGroup, AbstractControl } from '@angular/forms';
-import { MatTableDataSource } from '@angular/material/table';
+import { Component, OnInit, ViewChild } from '@angular/core';
-import { EIJob } from '../interfaces/ei.types';
-import { EIJobDataSource } from './ei-job.datasource';
import { UiService } from '../services/ui/ui.service';
+import { JobsListComponent } from './jobs-list/jobs-list.component';
import { ProducersListComponent } from './producers-list/producers-list.component';
@Component({
selector: 'nrcp-ei-coordinator',
templateUrl: './ei-coordinator.component.html',
- styleUrls: ['./ei-coordinator.component.scss']
+ styleUrls: ['./ei-coordinator.component.scss'],
+ providers: [
+ ProducersListComponent,
+ JobsListComponent
+ ]
})
export class EICoordinatorComponent implements OnInit {
darkMode: boolean;
- formGroup: FormGroup;
- jobsDataSource: MatTableDataSource<EIJob> = new MatTableDataSource<EIJob>();
+ @ViewChild(ProducersListComponent) producersList: ProducersListComponent;
+ @ViewChild(JobsListComponent) jobComponent: JobsListComponent;
- readonly jobsFormControl: AbstractControl;
constructor(
- private producersList: ProducersListComponent,
- private eiJobsDataSource: EIJobDataSource,
- private ui: UiService,
- private formBuilder: FormBuilder) {
- this.formGroup = formBuilder.group({ filter: [""] });
-
- this.jobsFormControl = formBuilder.group({
- id: '',
- typeId: '',
- owner: '',
- targetUri:''
- });
+ private ui: UiService) {
}
ngOnInit() {
- this.eiJobsDataSource.loadJobs();
-
- this.eiJobsDataSource.eiJobsSubject().subscribe((data) => {
- this.jobsDataSource.data = data;
- });
-
- this.jobsFormControl.valueChanges.subscribe(value => {
- const filter = {...value, id: value.id.trim().toLowerCase()} as string;
- this.jobsDataSource.filter = filter;
- });
-
- this.jobsDataSource.filterPredicate = ((data: EIJob, filter) => {
- return this.isDataIncluding(data.ei_job_identity, filter.id)
- && this.isDataIncluding(data.target_uri, filter.targetUri)
- && this.isDataIncluding(data.owner, filter.owner)
- && this.isDataIncluding(data.ei_type_identity, filter.typeId);
- }) as (data: EIJob, filter: any) => boolean;
-
this.ui.darkModeState.subscribe((isDark) => {
this.darkMode = isDark;
});
}
- sortJobs(sort: Sort){
- const data = this.jobsDataSource.data
- data.sort((a: EIJob, b: EIJob) => {
- const isAsc = sort.direction === 'asc';
- switch (sort.active) {
- case 'id': return this.compare(a.ei_job_identity, b.ei_job_identity, isAsc);
- case 'typeId': return this.compare(a.ei_type_identity, b.ei_type_identity, isAsc);
- case 'owner': return this.compare(a.owner, b.owner, isAsc);
- case 'targetUri': return this.compare(a.target_uri, b.owner, isAsc);
- default: return 0;
- }
- });
- this.jobsDataSource.data = data;
- }
-
- compare(a: any, b: any, isAsc: boolean) {
- return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
- }
-
- stopSort(event: any){
- event.stopPropagation();
- }
-
- isDataIncluding(data: string, filter: string) : boolean {
- return !filter || data.toLowerCase().includes(filter);
- }
-
- getJobTypeId(eiJob: EIJob): string {
- if (eiJob.ei_type_identity) {
- return eiJob.ei_type_identity;
- }
- return '< No type >';
- }
-
- getJobOwner(eiJob: EIJob): string {
- if (eiJob.owner) {
- return eiJob.owner;
- }
- return '< No owner >';
- }
refreshTables() {
- this.eiJobsDataSource.loadJobs();
- this.eiJobsDataSource.eiJobsSubject().subscribe((data) => {
- this.jobsDataSource.data = data;
- });
-
+ this.jobComponent.refresh();
this.producersList.refresh();
}
}
--- /dev/null
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2021 AT&T Intellectual Property
+ * Modifications Copyright (C) 2019 Nordix Foundation
+ * Modifications Copyright (C) 2020 Nordix Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { RouterModule, Routes } from '@angular/router';
+import { EICoordinatorComponent } from './ei-coordinator.component';
+import { ProducersListComponent } from './producers-list/producers-list.component';
+import { JobsListComponent } from './jobs-list/jobs-list.component';
+import { MatTableModule } from '@angular/material/table';
+import { MatIconModule } from '@angular/material/icon';
+import { MatInputModule } from '@angular/material/input';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { MatSortModule } from '@angular/material/sort';
+import { MatButtonModule } from '@angular/material/button';
+import { FlexLayoutModule } from '@angular/flex-layout';
+
+
+const routes: Routes = [
+ { path: 'ei-coordinator', component: EICoordinatorComponent }
+];
+
+@NgModule({
+ declarations: [
+ EICoordinatorComponent,
+ ProducersListComponent,
+ JobsListComponent
+ ],
+ imports: [
+ CommonModule,
+ FlexLayoutModule,
+ MatTableModule,
+ MatIconModule,
+ MatInputModule,
+ ReactiveFormsModule,
+ FormsModule,
+ MatSortModule,
+ MatButtonModule,
+ RouterModule.forChild(routes)
+ ],
+ exports: [
+ EICoordinatorComponent
+ ]
+})
+export class EiCoordinatorModule { }
let dataSource: EIJobDataSource;
let eiServiceSpy: any;
- const job = { ei_job_identity: '1', ei_job_data: 'data', ei_type_identity: 'Type ID 1', target_uri: 'hhtp://url', owner: 'owner'};
+ const job = { ei_job_identity: '1', ei_job_data: 'data', ei_type_identity: 'Type ID 1', target_uri: 'hhtp://url', owner: 'owner' };
beforeEach(() => {
eiServiceSpy = jasmine.createSpyObj('EIService', ['getProducerIds', 'getJobsForProducer']);
- eiServiceSpy.getProducerIds.and.returnValue(of([ 'producer1', 'producer2']));
+ eiServiceSpy.getProducerIds.and.returnValue(of(['producer1', 'producer2']));
eiServiceSpy.getJobsForProducer.and.returnValue(of([job]));
TestBed.configureTestingModule({
imports: [ToastrModule.forRoot()],
it('#getJobs', () => {
dataSource.loadJobs();
const actualJobs: EIJob[] = dataSource.eiJobs();
- expect(actualJobs).toEqual([ job, job ]);
+ expect(actualJobs).toEqual([job, job]);
expect(dataSource.rowCount).toEqual(2);
});
});
this.loadingSubject.next(true);
this.jobs = [];
this.eiSvc.getProducerIds().pipe(
- mergeMap(prodIds =>
+ mergeMap(prodIds =>
forkJoin(prodIds.map(id => this.eiSvc.getJobsForProducer(id)))),
mergeMap(result => result),
finalize(() => this.loadingSubject.next(false))
).subscribe(result => {
this.jobs = this.jobs.concat(result);
this.jobsSubject.next(this.jobs);
- } );
+ });
this.rowCount = this.jobs.length;
}
-
+
}
let eiServiceSpy: any;
let producer1 = {
- supported_ei_types: [ 'type1', 'type2' ]
+ supported_ei_types: ['type1', 'type2']
} as ProducerRegistrationInfo;
let producer2 = {
- supported_ei_types: [ 'type3', 'type4' ]
+ supported_ei_types: ['type3', 'type4']
} as ProducerRegistrationInfo;
let producerStatus1 = {
operational_state: OperationalState.ENABLED
let expectedProducer1 = {
ei_producer_id: 'producer1',
- ei_producer_types: [ 'type1', 'type2' ],
+ ei_producer_types: ['type1', 'type2'],
status: 'ENABLED'
} as EIProducer;
let expectedProducer2 = {
ei_producer_id: 'producer2',
- ei_producer_types: [ 'type3', 'type4' ],
+ ei_producer_types: ['type3', 'type4'],
status: 'DISABLED'
} as EIProducer;
beforeEach(() => {
eiServiceSpy = jasmine.createSpyObj('EIService', ['getProducerIds', 'getProducer', 'getProducerStatus']);
- eiServiceSpy.getProducerIds.and.returnValue(of([ 'producer1', 'producer2']));
+ eiServiceSpy.getProducerIds.and.returnValue(of(['producer1', 'producer2']));
eiServiceSpy.getProducer.and.returnValues(of(producer1), of(producer2));
eiServiceSpy.getProducerStatus.and.returnValues(of(producerStatus1), of(producerStatus2));
TestBed.configureTestingModule({
it('#loadProducers', () => {
dataSource.loadProducers();
const actualProducers: EIProducer[] = dataSource.eiProducers();
- expect(actualProducers).toEqual([ expectedProducer1, expectedProducer2 ]);
+ expect(actualProducers).toEqual([expectedProducer1, expectedProducer2]);
expect(dataSource.rowCount).toEqual(2);
});
});
this.producers = [];
this.eiSvc.getProducerIds().pipe(
- mergeMap(prodIds =>
+ mergeMap(prodIds =>
forkJoin(prodIds.map(id => {
return forkJoin([
of(id),
this.eiSvc.getProducerStatus(id)
])
})
- )),
+ )),
finalize(() => this.loadingSubject.next(false))
).subscribe(result => {
this.producers = result.map(producer => {
--- /dev/null
+<!--
+========================LICENSE_START=================================
+O-RAN-SC
+%%
+Copyright (C) 2021 Nordix Foundation
+%%
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+========================LICENSE_END===================================
+-->
+<div class="table-container">
+ <mat-table id="jobsTable" [dataSource]="jobsDataSource" fixedLayout matSort (matSortChange)="sortJobs($event)"
+ class="ei-coordinator-table mat-elevation-z8">
+ <ng-container matColumnDef="id">
+ <mat-header-cell *matHeaderCellDef mat-sort-header>
+ <div (click)="stopSort($event)">
+ <form style="display: flex" [formGroup]="jobForm">
+ <mat-form-field>
+ <input id="jobIdFilter" matInput formControlName="id">
+ <mat-placeholder>Job ID</mat-placeholder>
+ </mat-form-field>
+ </form>
+ </div>
+ </mat-header-cell>
+ <mat-cell *matCellDef="let eiJob"> {{eiJob.ei_job_identity}} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="typeId">
+ <mat-header-cell *matHeaderCellDef mat-sort-header>
+ <div (click)="stopSort($event)">
+ <form style="display: flex" [formGroup]="jobForm">
+ <mat-form-field>
+ <input id="jobTypeIdFilter" matInput formControlName="typeId">
+ <mat-placeholder>Type ID</mat-placeholder>
+ </mat-form-field>
+ </form>
+ </div>
+ </mat-header-cell>
+ <mat-cell *matCellDef="let eiJob">{{this.getJobTypeId(eiJob)}} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="owner">
+ <mat-header-cell *matHeaderCellDef mat-sort-header>
+ <div (click)="stopSort($event)">
+ <form style="display: flex" [formGroup]="jobForm">
+ <mat-form-field>
+ <input id="jobOwnerFilter" matInput formControlName="owner">
+ <mat-placeholder>Owner</mat-placeholder>
+ </mat-form-field>
+ </form>
+ </div>
+ </mat-header-cell>
+ <mat-cell *matCellDef="let eiJob">{{this.getJobOwner(eiJob)}} </mat-cell>
+ </ng-container>
+ <ng-container matColumnDef="targetUri">
+ <mat-header-cell *matHeaderCellDef mat-sort-header>
+ <div (click)="stopSort($event)">
+ <form style="display: flex" [formGroup]="jobForm">
+ <mat-form-field>
+ <input id="jobTargetUriFilter" matInput formControlName="targetUri">
+ <mat-placeholder>Target URI</mat-placeholder>
+ </mat-form-field>
+ </form>
+ </div>
+ </mat-header-cell>
+ <mat-cell *matCellDef="let eiJob"> {{eiJob.target_uri}} </mat-cell>
+ </ng-container>
+ <mat-header-row *matHeaderRowDef="['id', 'typeId', 'owner', 'targetUri']"></mat-header-row>
+ <mat-row *matRowDef="let row; columns: ['id', 'typeId', 'owner', 'targetUri'];"></mat-row>
+ </mat-table>
+</div>
\ No newline at end of file
--- /dev/null
+/*-\r
+ * ========================LICENSE_START=================================\r
+ * O-RAN-SC\r
+ * %%\r
+ * Copyright (C) 2021 Nordix Foundation\r
+ * %%\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ========================LICENSE_END===================================\r
+ */\r
+.ei-coordinator-table {\r
+ width: 100%;\r
+ min-height: 150px;\r
+ margin-top: 10px;\r
+ margin-bottom: 10px;\r
+ background-color: transparent;\r
+}\r
+\r
+.mat-form-field {\r
+ font-size: 14px;\r
+ width: 100%;\r
+}
\ No newline at end of file
--- /dev/null
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2021 Nordix Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+import { HarnessLoader } from '@angular/cdk/testing';
+import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule, FormBuilder } from '@angular/forms';
+import { MatInputHarness } from '@angular/material/input/testing';
+import { MatTableModule } from '@angular/material/table';
+import { MatTableHarness } from '@angular/material/table/testing';
+import { of } from 'rxjs/observable/of';
+import { EIJob } from 'src/app/interfaces/ei.types';
+import { UiService } from 'src/app/services/ui/ui.service';
+import { EIJobDataSource } from '../ei-job.datasource';
+
+import { JobsListComponent } from './jobs-list.component';
+
+describe('JobsListComponent', () => {
+ let component: JobsListComponent;
+ let fixture: ComponentFixture<JobsListComponent>;
+ let loader: HarnessLoader;
+ let eiJobComponent: jasmine.SpyObj<JobsListComponent>;
+ let jobDataSourceSpy: jasmine.SpyObj<EIJobDataSource>;
+
+ const job1 = {
+ ei_job_identity: 'job1',
+ ei_type_identity: 'type1',
+ owner: 'owner1',
+ target_uri: 'http://one'
+ } as EIJob;
+ const job2 = {
+ ei_job_identity: 'job2',
+ ei_type_identity: 'type2',
+ owner: 'owner2',
+ target_uri: 'http://two'
+ } as EIJob;
+
+ beforeEach(async(() => {
+ eiJobComponent = jasmine.createSpyObj('producersListSpy', ['refresh']);
+ jobDataSourceSpy = jasmine.createSpyObj('EIJobDataSource', ['loadJobs', 'eiJobs', 'eiJobsSubject']);
+
+ jobDataSourceSpy.eiJobsSubject.and.returnValue(of([job1, job2]));
+
+ TestBed.configureTestingModule({
+ imports: [
+ MatTableModule,
+ ReactiveFormsModule
+ ],
+ schemas: [
+ CUSTOM_ELEMENTS_SCHEMA
+ ],
+ declarations: [JobsListComponent],
+ providers: [
+ { provide: EIJobDataSource, useValue: jobDataSourceSpy },
+ UiService,
+ FormBuilder,
+ ]
+ })
+ .compileComponents();
+ }));
+
+ const expectedJob1Row = { id: 'job1', typeId: 'type1', owner: 'owner1', targetUri: 'http://one' };
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(JobsListComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ loader = TestbedHarnessEnvironment.loader(fixture);
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+
+ it('should contain job table with correct columns', async () => {
+ let producersTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' }));
+ let headerRow = (await producersTable.getHeaderRows())[0];
+ let headers = await headerRow.getCellTextByColumnName();
+
+ expect(headers).toEqual({ id: 'Job ID', typeId: 'Type ID', owner: 'Owner', targetUri: 'Target URI' });
+ });
+
+ it('should contain data after initialization', async () => {
+ component.ngOnInit();
+ const expectedJobRows = [
+ expectedJob1Row,
+ { id: 'job2', typeId: 'type2', owner: 'owner2', targetUri: 'http://two' }
+ ];
+ let jobsTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' }));
+ let jobRows = await jobsTable.getRows();
+ expect(jobRows.length).toEqual(2);
+ jobRows.forEach(row => {
+ row.getCellTextByColumnName().then(values => {
+ expect(expectedJobRows).toContain(jasmine.objectContaining(values));
+ });
+ });
+ });
+
+ it('should display default values for non required properties ', async () => {
+ const jobMissingProperties = {
+ ei_job_identity: 'job1',
+ target_uri: 'http://one'
+ } as EIJob;
+ const jobs: EIJob[] = [jobMissingProperties];
+ jobDataSourceSpy.eiJobsSubject.and.returnValue(of(jobs));
+ component.ngOnInit();
+
+ const expectedJobRow = { id: 'job1', typeId: '< No type >', owner: '< No owner >', targetUri: 'http://one' };
+ let jobsTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' }));
+ let jobRows = await jobsTable.getRows();
+ expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJobRow);
+ });
+
+ it('filtering', async () => {
+ component.ngOnInit();
+ let jobsTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' }));
+
+ let idFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobIdFilter' }));
+ await idFilterInput.setValue("1");
+ let jobRows = await jobsTable.getRows();
+ expect(jobRows.length).toEqual(1);
+ expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJob1Row);
+
+ idFilterInput.setValue('');
+ let typeIdFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobTypeIdFilter' }));
+ await typeIdFilterInput.setValue("1");
+ jobRows = await jobsTable.getRows();
+ expect(jobRows.length).toEqual(1);
+
+ typeIdFilterInput.setValue('');
+ let ownerFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobOwnerFilter' }));
+ await ownerFilterInput.setValue("1");
+ jobRows = await jobsTable.getRows();
+ expect(jobRows.length).toEqual(1);
+ expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJob1Row);
+
+ ownerFilterInput.setValue('');
+ let targetUriFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobTargetUriFilter' }));
+ await targetUriFilterInput.setValue("one");
+ jobRows = await jobsTable.getRows();
+ expect(jobRows.length).toEqual(1);
+ expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJob1Row);
+ });
+});
--- /dev/null
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2021 Nordix Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+import { Component, OnInit } from '@angular/core';
+import { FormControl, FormGroup } from '@angular/forms';
+import { Sort } from '@angular/material/sort';
+import { MatTableDataSource } from '@angular/material/table';
+import { EIJob } from 'src/app/interfaces/ei.types';
+import { UiService } from 'src/app/services/ui/ui.service';
+import { EIJobDataSource } from '../ei-job.datasource';
+
+@Component({
+ selector: 'nrcp-jobs-list',
+ templateUrl: './jobs-list.component.html',
+ styleUrls: ['./jobs-list.component.scss']
+})
+export class JobsListComponent implements OnInit {
+ darkMode: boolean;
+ jobsDataSource: MatTableDataSource<EIJob> = new MatTableDataSource<EIJob>();
+
+ jobForm: FormGroup;
+
+ constructor(
+ private eiJobsDataSource: EIJobDataSource,
+ private ui: UiService
+ ) {
+ this.jobForm = new FormGroup({
+ id: new FormControl(''),
+ typeId: new FormControl(''),
+ owner: new FormControl(''),
+ targetUri: new FormControl('')
+ });
+
+ }
+
+ ngOnInit(): void {
+ this.refresh();
+
+ this.jobForm.valueChanges.subscribe(value => {
+ const filter = { ...value, id: value.id.trim().toLowerCase() } as string;
+ this.jobsDataSource.filter = filter;
+ });
+
+ this.jobsDataSource.filterPredicate = ((data: EIJob, filter) => {
+ return this.isDataIncluding(data.ei_job_identity, filter.id)
+ && this.isDataIncluding(data.target_uri, filter.targetUri)
+ && this.isDataIncluding(data.owner, filter.owner)
+ && this.isDataIncluding(data.ei_type_identity, filter.typeId);
+ }) as (data: EIJob, filter: any) => boolean;
+
+ this.ui.darkModeState.subscribe((isDark) => {
+ this.darkMode = isDark;
+ });
+ }
+
+ sortJobs(sort: Sort) {
+ const data = this.jobsDataSource.data
+ data.sort((a: EIJob, b: EIJob) => {
+ const isAsc = sort.direction === 'asc';
+ switch (sort.active) {
+ case 'id': return this.compare(a.ei_job_identity, b.ei_job_identity, isAsc);
+ case 'typeId': return this.compare(a.ei_type_identity, b.ei_type_identity, isAsc);
+ case 'owner': return this.compare(a.owner, b.owner, isAsc);
+ case 'targetUri': return this.compare(a.target_uri, b.owner, isAsc);
+ default: return 0;
+ }
+ });
+ this.jobsDataSource.data = data;
+ }
+
+ compare(a: any, b: any, isAsc: boolean) {
+ return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
+ }
+
+ stopSort(event: any) {
+ event.stopPropagation();
+ }
+
+ isDataIncluding(data: string, filter: string): boolean {
+ return !filter || data.toLowerCase().includes(filter);
+ }
+
+ getJobTypeId(eiJob: EIJob): string {
+ if (eiJob.ei_type_identity) {
+ return eiJob.ei_type_identity;
+ }
+ return '< No type >';
+ }
+
+ getJobOwner(eiJob: EIJob): string {
+ if (eiJob.owner) {
+ return eiJob.owner;
+ }
+ return '< No owner >';
+ }
+
+ refresh() {
+ this.eiJobsDataSource.loadJobs();
+
+ this.eiJobsDataSource.eiJobsSubject().subscribe((data) => {
+ this.jobsDataSource.data = data;
+ });
+ }
+
+}
+<!--
+========================LICENSE_START=================================
+O-RAN-SC
+%%
+Copyright (C) 2021 Nordix Foundation
+%%
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+========================LICENSE_END===================================
+-->
<div class="table-container">
- <mat-table id="producersTable" [dataSource]="producersDataSource" fixedLayout
- matSort (matSortChange)="sortProducers($event)"
- class="ei-coordinator-table mat-elevation-z8">
- <ng-container matColumnDef="id">
- <mat-header-cell *matHeaderCellDef mat-sort-header>
- <div (click)="stopSort($event)">
- <form style="display: flex" [formGroup]="producersFormControl">
+ <mat-table id="producersTable" [dataSource]="producersDataSource" fixedLayout matSort
+ (matSortChange)="sortProducers($event)" class="ei-coordinator-table mat-elevation-z8">
+ <ng-container matColumnDef="id">
+ <mat-header-cell *matHeaderCellDef mat-sort-header>
+ <div (click)="stopSort($event)">
+ <form style="display: flex" [formGroup]="producerForm">
<mat-form-field>
<input id="producerIdFilter" matInput formControlName="ei_producer_id">
<mat-placeholder>Producer ID</mat-placeholder>
</mat-form-field>
</form>
</div>
- </mat-header-cell>
- <mat-cell *matCellDef="let eiProducer"> {{eiProducer.ei_producer_id}} </mat-cell>
- </ng-container>
+ </mat-header-cell>
+ <mat-cell *matCellDef="let eiProducer"> {{eiProducer.ei_producer_id}} </mat-cell>
+ </ng-container>
- <ng-container matColumnDef="types">
- <mat-header-cell *matHeaderCellDef mat-sort-header>
- <div (click)="stopSort($event)">
- <form style="display: flex" [formGroup]="producersFormControl">
+ <ng-container matColumnDef="types">
+ <mat-header-cell *matHeaderCellDef mat-sort-header>
+ <div (click)="stopSort($event)">
+ <form style="display: flex" [formGroup]="producerForm">
<mat-form-field>
<input id="producerTypesFilter" matInput formControlName="ei_producer_types">
<mat-placeholder>Producer types</mat-placeholder>
</mat-form-field>
</form>
- </div>
- </mat-header-cell>
- <mat-cell *matCellDef="let eiProducer"> {{this.getProducerTypes(eiProducer)}} </mat-cell>
- </ng-container>
+ </div>
+ </mat-header-cell>
+ <mat-cell *matCellDef="let eiProducer"> {{this.getProducerTypes(eiProducer)}} </mat-cell>
+ </ng-container>
- <ng-container matColumnDef="status">
- <mat-header-cell *matHeaderCellDef mat-sort-header>
- <div (click)="stopSort($event)">
- <form style="display: flex" [formGroup]="producersFormControl">
+ <ng-container matColumnDef="status">
+ <mat-header-cell *matHeaderCellDef mat-sort-header>
+ <div (click)="stopSort($event)">
+ <form style="display: flex" [formGroup]="producerForm">
<mat-form-field>
<input id="producerStatusFilter" matInput formControlName="status">
<mat-placeholder>Producer status</mat-placeholder>
</mat-form-field>
</form>
- </div>
- </mat-header-cell>
- <mat-cell *matCellDef="let eiProducer"> {{this.getProducerStatus(eiProducer)}} </mat-cell>
- </ng-container>
+ </div>
+ </mat-header-cell>
+ <mat-cell *matCellDef="let eiProducer"> {{this.getProducerStatus(eiProducer)}} </mat-cell>
+ </ng-container>
- <mat-header-row *matHeaderRowDef="['id', 'types', 'status']"></mat-header-row>
- <mat-row *matRowDef="let row; columns: ['id', 'types', 'status'];"></mat-row>
- </mat-table>
- </div>
+ <mat-header-row *matHeaderRowDef="['id', 'types', 'status']"></mat-header-row>
+ <mat-row *matRowDef="let row; columns: ['id', 'types', 'status'];"></mat-row>
+ </mat-table>
+</div>
\ No newline at end of file
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2021 Nordix Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
.ei-coordinator-table {
- width: 100%;
- min-height: 150px;
- margin-top: 10px;
- margin-bottom: 10px;
- background-color: transparent;
- }
+ width: 100%;
+ min-height: 150px;
+ margin-top: 10px;
+ margin-bottom: 10px;
+ background-color: transparent;
+}
+.mat-form-field {
+ font-size: 14px;
+ width: 100%;
+}
\ No newline at end of file
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2021 Nordix Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { MatTableModule } from '@angular/material/table';
import { MatTableHarness } from '@angular/material/table/testing';
import { of } from 'rxjs/observable/of';
-import { EIProducer } from 'src/app/interfaces/ei.types';
-import { UiService } from 'src/app/services/ui/ui.service';
+import { EIProducer } from '../../interfaces/ei.types';
+import { UiService } from '../../services/ui/ui.service';
import { EIProducerDataSource } from '../ei-producer.datasource';
import { ProducersListComponent } from './producers-list.component';
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2021 Nordix Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
import { Component, OnInit } from '@angular/core';
-import { AbstractControl, FormBuilder } from '@angular/forms';
+import { FormControl, FormGroup } from '@angular/forms';
import { Sort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
-import { EIProducer } from 'src/app/interfaces/ei.types';
-import { UiService } from 'src/app/services/ui/ui.service';
+import { EIProducer } from '../../interfaces/ei.types';
+import { UiService } from '../../services/ui/ui.service';
import { EIProducerDataSource } from '../ei-producer.datasource';
@Component({
export class ProducersListComponent implements OnInit {
darkMode: boolean;
producersDataSource: MatTableDataSource<EIProducer> = new MatTableDataSource<EIProducer>();
-
- readonly producersFormControl: AbstractControl;
+ producerForm: FormGroup;
constructor(
private eiProducersDataSource: EIProducerDataSource,
- private ui: UiService,
- private formBuilder: FormBuilder) {
- this.producersFormControl = formBuilder.group({
- ei_producer_id: '',
- ei_producer_types: '',
- status: ''
+ private ui: UiService) {
+
+ this.producerForm = new FormGroup({
+ ei_producer_id: new FormControl(''),
+ ei_producer_types: new FormControl(''),
+ status: new FormControl('')
});
}
ngOnInit(): void {
this.refresh();
- this.producersFormControl.valueChanges.subscribe(value => {
+ this.producerForm.valueChanges.subscribe(value => {
const filter = { ...value, ei_producer_id: value.ei_producer_id.trim().toLowerCase() } as string;
this.producersDataSource.filter = filter;
});