it('should refresh tables', async () => {
let refreshButton = await loader.getHarness(MatButtonHarness.with({ selector: '#refreshButton' }));
- spyOn(component.producersList, 'refresh');
- spyOn(component.jobComponent, 'refresh');
+ spyOn(component.producersList, 'loadProducers');
+ spyOn(component.jobComponent, 'loadJobs');
await refreshButton.click();
- expect(component.jobComponent.refresh).toHaveBeenCalled();
- expect(component.producersList.refresh).toHaveBeenCalled();
+ expect(component.jobComponent.loadJobs).toHaveBeenCalled();
+ expect(component.producersList.loadProducers).toHaveBeenCalled();
});
});
]
})
class JobsListStubComponent {
- refresh() { }
+ loadJobs() { }
}
@Component({
]
})
class ProducerListStubComponent {
- refresh() { }
+ loadProducers() { }
}
});
}
refreshTables() {
- this.jobComponent.refresh();
- this.producersList.refresh();
+ this.jobComponent.loadJobs();
+ this.producersList.loadProducers();
}
}
import { MatButtonModule } from '@angular/material/button';
import { FlexLayoutModule } from '@angular/flex-layout';
import { EiCardComponent } from './ei-card/ei-card.component';
+import { MatPaginatorModule } from '@angular/material/paginator';
+import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
const routes: Routes = [
ReactiveFormsModule,
FormsModule,
MatSortModule,
+ MatPaginatorModule,
MatButtonModule,
+ MatProgressSpinnerModule,
RouterModule.forChild(routes)
],
exports: [
+++ /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 { TestBed } from '@angular/core/testing';
-import { of } from 'rxjs';
-
-import { EIJobDataSource } from './ei-job.datasource';
-import { EIService } from '../services/ei/ei.service';
-import { ToastrModule } from 'ngx-toastr';
-import { EIJob } from '../interfaces/ei.types';
-
-describe('EIJobDataSource', () => {
- 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' };
-
- beforeEach(() => {
- eiServiceSpy = jasmine.createSpyObj('EIService', ['getProducerIds', 'getJobsForProducer']);
-
- eiServiceSpy.getProducerIds.and.returnValue(of(['producer1', 'producer2']));
- eiServiceSpy.getJobsForProducer.and.returnValue(of([job]));
- TestBed.configureTestingModule({
- imports: [ToastrModule.forRoot()],
- providers: [
- { provide: EIService, useValue: eiServiceSpy }
- ]
- });
- });
-
- it('should create', () => {
- dataSource = TestBed.inject(EIJobDataSource);
- expect(dataSource).toBeTruthy();
- });
-
- it('#getJobs', () => {
- dataSource.loadJobs();
- const actualJobs: EIJob[] = dataSource.eiJobs();
- expect(actualJobs).toEqual([job, job]);
- expect(dataSource.rowCount).toEqual(2);
- });
-});
+++ /dev/null
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 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 { Injectable } from '@angular/core';
-
-import { BehaviorSubject } from 'rxjs/BehaviorSubject';
-import { mergeMap, finalize } from 'rxjs/operators';
-import { Observable, forkJoin } from 'rxjs';
-
-import { EIJob } from '../interfaces/ei.types';
-import { EIService } from '../services/ei/ei.service';
-
-
-@Injectable({
- providedIn: 'root'
-})
-
-export class EIJobDataSource {
-
- private jobs: Array<EIJob> = [];
-
- public eiJobs(): EIJob[] {
- return this.jobs;
- }
-
- public eiJobsSubject(): Observable<EIJob[]> {
- return this.jobsSubject.asObservable() as Observable<EIJob[]>;
- }
-
- private loadingSubject = new BehaviorSubject<boolean>(false);
- private jobsSubject = new BehaviorSubject<EIJob[]>([]);
-
- public loading$ = this.loadingSubject.asObservable();
-
- public rowCount = 1; // hide footer during intial load
-
- constructor(
- private eiSvc: EIService) {
- }
-
- loadJobs() {
- this.loadingSubject.next(true);
- this.jobs = [];
- this.eiSvc.getProducerIds().pipe(
- 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;
- }
-
-
-}
+++ /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 { TestBed } from '@angular/core/testing';
-import { of } from 'rxjs';
-
-import { EIService } from '../services/ei/ei.service';
-import { ToastrModule } from 'ngx-toastr';
-import { EIProducer, OperationalState, ProducerRegistrationInfo, ProducerStatus } from '../interfaces/ei.types';
-import { EIProducerDataSource } from './ei-producer.datasource';
-
-describe('EIProducerDataSource', () => {
- let dataSource: EIProducerDataSource;
- let eiServiceSpy: any;
-
- let producer1 = {
- supported_ei_types: ['type1', 'type2']
- } as ProducerRegistrationInfo;
- let producer2 = {
- supported_ei_types: ['type3', 'type4']
- } as ProducerRegistrationInfo;
- let producerStatus1 = {
- operational_state: OperationalState.ENABLED
- } as ProducerStatus;
- let producerStatus2 = {
- operational_state: OperationalState.DISABLED
- } as ProducerStatus;
-
- let expectedProducer1 = {
- ei_producer_id: 'producer1',
- ei_producer_types: ['type1', 'type2'],
- status: 'ENABLED'
- } as EIProducer;
- let expectedProducer2 = {
- ei_producer_id: 'producer2',
- 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.getProducer.and.returnValues(of(producer1), of(producer2));
- eiServiceSpy.getProducerStatus.and.returnValues(of(producerStatus1), of(producerStatus2));
- TestBed.configureTestingModule({
- imports: [ToastrModule.forRoot()],
- providers: [
- { provide: EIService, useValue: eiServiceSpy }
- ]
- });
- });
-
- it('should create', () => {
- dataSource = TestBed.inject(EIProducerDataSource);
- expect(dataSource).toBeTruthy();
- });
-
- it('#loadProducers', () => {
- dataSource.loadProducers();
- const actualProducers: EIProducer[] = dataSource.eiProducers();
- expect(actualProducers).toEqual([expectedProducer1, expectedProducer2]);
- expect(dataSource.rowCount).toEqual(2);
- });
-});
+++ /dev/null
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 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 { Injectable } from '@angular/core';
-
-import { BehaviorSubject } from 'rxjs/BehaviorSubject';
-import { mergeMap, finalize } from 'rxjs/operators';
-import { Observable, forkJoin, of } from 'rxjs';
-
-import { EIProducer } from '../interfaces/ei.types';
-import { EIService } from '../services/ei/ei.service';
-
-@Injectable({
- providedIn: 'root'
-})
-
-export class EIProducerDataSource {
-
- private producers: Array<EIProducer> = [];
-
- public eiProducers(): EIProducer[] {
- return this.producers;
- }
-
- public eiProducersSubject(): Observable<EIProducer[]> {
- return this.producersSubject.asObservable() as Observable<EIProducer[]>;
- }
-
- private loadingSubject = new BehaviorSubject<boolean>(false);
- private producersSubject = new BehaviorSubject<EIProducer[]>([]);
-
- public loading$ = this.loadingSubject.asObservable();
-
- public rowCount = 1; // hide footer during intial load
-
- constructor(
- private eiSvc: EIService) {
- }
-
- loadProducers() {
- this.loadingSubject.next(true);
- this.producers = [];
-
- this.eiSvc.getProducerIds().pipe(
- mergeMap(prodIds =>
- forkJoin(prodIds.map(id => {
- return forkJoin([
- of(id),
- this.eiSvc.getProducer(id),
- this.eiSvc.getProducerStatus(id)
- ])
- })
- )),
- finalize(() => this.loadingSubject.next(false))
- ).subscribe(result => {
- this.producers = result.map(producer => {
- let eiProducer = <EIProducer>{};
- eiProducer.ei_producer_id = producer[0];
- eiProducer.ei_producer_types = producer[1].supported_ei_types;
- eiProducer.status = producer[2].operational_state.toString();
- return eiProducer;
- });
- this.producersSubject.next(this.producers);
- });
- this.rowCount = this.producers.length;
- }
-}
\ No newline at end of file
========================LICENSE_END===================================
-->
<div class="table-container">
+ <div class="spinner-container" style="display: flex; justify-content: center; align-items: center;"
+ *ngIf="loading$ | async">
+ <mat-spinner></mat-spinner>
+ </div>
<mat-table id="jobsTable" [dataSource]="jobsDataSource" fixedLayout matSort (matSortChange)="sortJobs($event)"
- class="ei-coordinator-table mat-elevation-z8">
+ matSortDisableClear matSortDirection="asc" class="ei-coordinator-table mat-elevation-z8">
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header>
<div (click)="stopSort($event)">
<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>
+ <mat-paginator [length]="jobs()?.length" [pageSize]="10" [pageSizeOptions]="[5, 10, 25, 100]" showFirstLastButtons
+ class="ei-coordinator-table mat-elevation-z8"></mat-paginator>
</div>
\ No newline at end of file
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 { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatInputModule } from '@angular/material/input';
import { MatInputHarness } from '@angular/material/input/testing';
+import { MatPaginatorModule } from '@angular/material/paginator';
+import { MatSortModule } from '@angular/material/sort';
+import { MatSortHarness } from '@angular/material/sort/testing';
+import { MatPaginatorHarness } from '@angular/material/paginator/testing';
import { MatTableModule } from '@angular/material/table';
import { MatTableHarness } from '@angular/material/table/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
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 { EIJob } from '../../interfaces/ei.types';
+import { EIService } from '../../services/ei/ei.service';
+import { UiService } from '../../services/ui/ui.service';
import { JobsListComponent } from './jobs-list.component';
+let component: JobsListComponent;
+let fixture: ComponentFixture<JobsListComponent>;
+
+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;
+
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]));
+ const spy = jasmine.createSpyObj('EIService', ['getProducerIds', 'getJobsForProducer']);
TestBed.configureTestingModule({
imports: [
MatTableModule,
- ReactiveFormsModule
- ],
- schemas: [
- CUSTOM_ELEMENTS_SCHEMA
+ MatPaginatorModule,
+ FormsModule,
+ MatSortModule,
+ ReactiveFormsModule,
+ BrowserAnimationsModule,
+ MatFormFieldModule,
+ MatInputModule
],
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [JobsListComponent],
providers: [
- { provide: EIJobDataSource, useValue: jobDataSourceSpy },
- UiService,
- FormBuilder,
+ { provide: EIService, useValue: spy },
+ UiService
]
})
- .compileComponents();
+ .compileComponents()
+ .then(() => {
+ fixture = TestBed.createComponent(JobsListComponent);
+ component = fixture.componentInstance;
+ loader = TestbedHarnessEnvironment.loader(fixture);
+ });
}));
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();
+ describe('#content', () => {
+
+ it('should loadJobs', () => {
+ setServiceSpy();
+ component.loadJobs();
+ const actualJobs: EIJob[] = component.jobs();
+ expect(actualJobs.length).toEqual(4);
+ expect(actualJobs).toEqual([job1, job2, job1, job2]);
+ });
+
+ it('should contain job table with correct columns', async () => {
+ setServiceSpy();
+ let jobsTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' }));
+ let headerRow = (await jobsTable.getHeaderRows())[0];
+ let headers = await headerRow.getCellTextByColumnName();
+
+ expect(headers).toEqual({ id: 'Job ID', typeId: 'Type ID', owner: 'Owner', targetUri: 'Target URI' });
+ });
+
+ it('should set correct dark mode from UIService', () => {
+ setServiceSpy();
+ component.ngOnInit();
+ const uiService: UiService = TestBed.inject(UiService);
+ expect(component.darkMode).toBeTruthy();
- expect(headers).toEqual({ id: 'Job ID', typeId: 'Type ID', owner: 'Owner', targetUri: 'Target URI' });
+ uiService.darkModeState.next(false);
+ fixture.detectChanges();
+ expect(component.darkMode).toBeFalsy();
+ });
});
- 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));
+ describe('#jobsTable', () => {
+
+ it('should contain data after initialization', async () => {
+ setServiceSpy();
+ 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(4);
+ 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('should display default values for non required properties ', async () => {
+
+ const jobMissingProperties = {
+ "ei_job_identity": "job1",
+ "ei_job_data": {
+ "jobparam2": "value2_job2",
+ "jobparam3": "value3_job2",
+ "jobparam1": "value1_job2"
+ },
+ "target_uri": "http://one"
+ } as EIJob;
+
+ let eiServiceSpy = TestBed.inject(EIService) as jasmine.SpyObj<EIService>;
+ eiServiceSpy.getProducerIds.and.returnValue(of(['producer1']));
+ eiServiceSpy.getJobsForProducer.and.returnValue(of([jobMissingProperties]));
+
+ 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 () => {
+ setServiceSpy();
+ component.ngOnInit();
+ let jobsTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' }));
- 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);
+ let idFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobIdFilter' }));
+ await idFilterInput.setValue("1");
+ let jobRows = await jobsTable.getRows();
+ expect(jobRows.length).toEqual(2);
+ 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(2);
+
+ typeIdFilterInput.setValue('');
+ let ownerFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#jobOwnerFilter' }));
+ await ownerFilterInput.setValue("1");
+ jobRows = await jobsTable.getRows();
+ expect(jobRows.length).toEqual(2);
+ 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(2);
+ expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJob1Row);
+ });
+
+ describe('#sorting', () => {
+
+ it('should verify sort functionality on the table', async () => {
+ setServiceSpy();
+ const sort = await loader.getHarness(MatSortHarness);
+ let headers = await sort.getSortHeaders({ sortDirection: '' });
+ expect(headers.length).toBe(4);
+
+ await headers[0].click();
+ expect(await headers[0].isActive()).toBe(true);
+ expect(await headers[0].getSortDirection()).toBe('asc');
+
+ await headers[0].click();
+ expect(await headers[0].getSortDirection()).toBe('desc');
+
+ });
+
+ it('should sort table asc and desc by first header', async () => {
+ setServiceSpy();
+ const sort = await loader.getHarness(MatSortHarness);
+ let jobsTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' }));
+ const firstHeader = (await sort.getSortHeaders())[0];
+ expect(await firstHeader.getSortDirection()).toBe('');
+
+ await firstHeader.click();
+ expect(await firstHeader.getSortDirection()).toBe('asc');
+ let jobRows = await jobsTable.getRows();
+ jobRows = await jobsTable.getRows();
+ expect(await jobRows[0].getCellTextByColumnName()).toEqual(expectedJob1Row);
+
+ await firstHeader.click();
+ expect(await firstHeader.getSortDirection()).toBe('desc');
+ jobRows = await jobsTable.getRows();
+ expect(await jobRows[jobRows.length - 1].getCellTextByColumnName()).toEqual(expectedJob1Row);
+ });
+ });
+
+ describe('#paging', () => {
+ it('should work properly on the table', async () => {
+ let eiServiceSpy = TestBed.inject(EIService) as jasmine.SpyObj<EIService>;
+ eiServiceSpy.getProducerIds.and.returnValue(of(['producer1', 'producer2']));
+ eiServiceSpy.getJobsForProducer.and.returnValue(of([job1, job2, job1]));
+
+ const paging = await loader.getHarness(MatPaginatorHarness);
+ await paging.setPageSize(5);
+
+ let jobsTable = await loader.getHarness(MatTableHarness.with({ selector: '#jobsTable' }));
+ let jobRows = await jobsTable.getRows();
+ expect(jobRows.length).toEqual(5);
+
+ await paging.goToNextPage();
+ jobRows = await jobsTable.getRows();
+ expect(jobRows.length).toEqual(1);
+ expect(await jobRows[jobRows.length - 1].getCellTextByColumnName()).toEqual(expectedJob1Row);
+ });
+ });
});
});
+
+function setServiceSpy() {
+ let eiServiceSpy = TestBed.inject(EIService) as jasmine.SpyObj<EIService>;
+ eiServiceSpy.getProducerIds.and.returnValue(of(['producer1', 'producer2']));
+ eiServiceSpy.getJobsForProducer.and.returnValue(of([job1, job2]));
+}
* limitations under the License.
* ========================LICENSE_END===================================
*/
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, ViewChild } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
+import { MatPaginator } from '@angular/material/paginator';
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';
+import { forkJoin } from 'rxjs';
+import { BehaviorSubject } from 'rxjs/BehaviorSubject';
+import { mergeMap, finalize } from 'rxjs/operators';
+import { EIJob } from '../../interfaces/ei.types';
+import { EIService } from '../../services/ei/ei.service';
+import { UiService } from '../../services/ui/ui.service';
@Component({
selector: 'nrcp-jobs-list',
styleUrls: ['./jobs-list.component.scss']
})
export class JobsListComponent implements OnInit {
+
+ @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
+
darkMode: boolean;
jobsDataSource: MatTableDataSource<EIJob> = new MatTableDataSource<EIJob>();
-
jobForm: FormGroup;
+ private loadingSubject = new BehaviorSubject<boolean>(false);
+ private jobsSubject = new BehaviorSubject<EIJob[]>([]);
+ public loading$ = this.loadingSubject.asObservable();
constructor(
- private eiJobsDataSource: EIJobDataSource,
+ private eiSvc: EIService,
private ui: UiService
) {
this.jobForm = new FormGroup({
owner: new FormControl(''),
targetUri: new FormControl('')
});
-
}
ngOnInit(): void {
- this.refresh();
+ this.loadJobs();
+ this.jobsSubject.subscribe((data) => {
+ this.jobsDataSource = new MatTableDataSource<EIJob>(data);
+ //this.jobsDataSource.data = data;
+ this.jobsDataSource.paginator = this.paginator;
+ });
this.jobForm.valueChanges.subscribe(value => {
const filter = { ...value, id: value.id.trim().toLowerCase() } as string;
});
}
+ ngOnDestroy() {
+ if (!this.jobsSubject) this.jobsSubject.unsubscribe();
+ if (!this.loadingSubject) this.loadingSubject.unsubscribe();
+ if (!this.ui.darkModeState) this.ui.darkModeState.unsubscribe();
+ }
+
sortJobs(sort: Sort) {
const data = this.jobsDataSource.data
data.sort((a: EIJob, b: EIJob) => {
return '< No owner >';
}
- refresh() {
- this.eiJobsDataSource.loadJobs();
+ public jobs(): EIJob[] {
+ return this.jobsSubject.value;
+ }
- this.eiJobsDataSource.eiJobsSubject().subscribe((data) => {
- this.jobsDataSource.data = data;
+ loadJobs() {
+ this.loadingSubject.next(true);
+ let jobs = [];
+ this.eiSvc.getProducerIds().pipe(
+ mergeMap(prodIds =>
+ forkJoin(prodIds.map(id => this.eiSvc.getJobsForProducer(id)))),
+ mergeMap(result => result),
+ finalize(() => this.loadingSubject.next(false))
+ ).subscribe(result => {
+ jobs = jobs.concat(result);
+ this.jobsSubject.next(jobs);
});
}
========================LICENSE_END===================================
-->
<div class="table-container">
- <mat-table id="producersTable" [dataSource]="producersDataSource" fixedLayout matSort
- (matSortChange)="sortProducers($event)" class="ei-coordinator-table mat-elevation-z8">
+ <mat-table id="producersTable" [dataSource]="producersDataSource" fixedLayout
+ class="ei-coordinator-table mat-elevation-z8" matSort matSortDisableClear matSortDirection="asc"
+ (matSortChange)="sortProducers($event)">
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header>
<div (click)="stopSort($event)">
-/*-
- * ========================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 { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
+import { HarnessLoader } from '@angular/cdk/testing';
+import { MatTableHarness } from '@angular/material/table/testing';
+import { MatSortHarness } from '@angular/material/sort/testing';
+import { ProducersListComponent } from "./producers-list.component";
+import { EIService } from 'src/app/services/ei/ei.service';
+import { EIProducer, OperationalState, ProducerRegistrationInfo, ProducerStatus } from 'src/app/interfaces/ei.types';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
-import { MatInputHarness } from '@angular/material/input/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { MatIconModule } from '@angular/material/icon';
import { MatTableModule } from '@angular/material/table';
-import { MatTableHarness } from '@angular/material/table/testing';
-import { of } from 'rxjs/observable/of';
-import { EIProducer } from '../../interfaces/ei.types';
-import { UiService } from '../../services/ui/ui.service';
-import { EIProducerDataSource } from '../ei-producer.datasource';
+import { MatInputHarness } from '@angular/material/input/testing';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { UiService } from 'src/app/services/ui/ui.service';
+import { of } from 'rxjs';
+import { MatSortModule } from '@angular/material/sort';
-import { ProducersListComponent } from './producers-list.component';
+let component: ProducersListComponent;
+let fixture: ComponentFixture<ProducersListComponent>;
describe('ProducersListComponent', () => {
- let component: ProducersListComponent;
- let fixture: ComponentFixture<ProducersListComponent>;
+
let loader: HarnessLoader;
- let producerDataSourceSpy: jasmine.SpyObj<EIProducerDataSource>;
-
- const producer1 = {
- ei_producer_id: 'producer1',
- ei_producer_types: ['type1', 'type2'],
- status: 'ENABLED'
- } as EIProducer;
- const producer2 = {
- ei_producer_id: 'producer2',
- ei_producer_types: ['type2', 'type3'],
- status: 'DISABLED'
- } as EIProducer;
beforeEach(async(() => {
- producerDataSourceSpy = jasmine.createSpyObj('EIProducerDataSource', ['loadProducers', 'eiProducers', 'eiProducersSubject']);
-
- const producers: EIProducer[] = [producer1, producer2];
- producerDataSourceSpy.eiProducersSubject.and.returnValue(of(producers));
+ const spy = jasmine.createSpyObj('EIService', ['getProducerIds', 'getProducer', 'getProducerStatus']);
TestBed.configureTestingModule({
imports: [
+ MatIconModule,
MatTableModule,
+ MatSortModule,
+ BrowserAnimationsModule,
ReactiveFormsModule
],
schemas: [
ProducersListComponent
],
providers: [
- { provide: EIProducerDataSource, useValue: producerDataSourceSpy },
+ { provide: EIService, useValue: spy },
UiService,
- FormBuilder,
]
})
- .compileComponents();
+ .compileComponents()
+ .then(() => {
+ fixture = TestBed.createComponent(ProducersListComponent);
+ component = fixture.componentInstance;
+ loader = TestbedHarnessEnvironment.loader(fixture);
+ });
}));
- const expectedProducer1Row = { id: 'producer1', types: 'type1,type2', status: 'ENABLED' };
- beforeEach(() => {
- fixture = TestBed.createComponent(ProducersListComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- loader = TestbedHarnessEnvironment.loader(fixture);
- });
-
it('should create', () => {
expect(component).toBeTruthy();
});
- it('should contain producers table with correct columns', async () => {
- let producersTable = await loader.getHarness(MatTableHarness.with({ selector: '#producersTable' }));
- let headerRow = (await producersTable.getHeaderRows())[0];
- let headers = await headerRow.getCellTextByColumnName();
+ describe('#content', () => {
- expect(headers).toEqual({ id: 'Producer ID', types: 'Producer types', status: 'Producer status' });
- });
+ it('should loadProducers', () => {
+ const producer1 = {
+ ei_producer_id: 'producer1',
+ ei_producer_types: ['type1', 'type2'],
+ status: 'ENABLED'
+ } as EIProducer;
+ const producer2 = {
+ ei_producer_id: 'producer2',
+ ei_producer_types: ['type2', 'type3'],
+ status: 'DISABLED'
+ } as EIProducer;
+ setServiceSpy();
+ component.loadProducers();
+ const actualProducers: EIProducer[] = component.eiProducers();
+ expect(actualProducers).toEqual([producer1, producer2]);
+ });
- it('should contain data after initialization', async () => {
- component.ngOnInit();
- const expectedProducerRows = [
- expectedProducer1Row,
- { id: 'producer2', types: 'type2,type3', status: 'DISABLED' }
- ];
- let producersTable = await loader.getHarness(MatTableHarness.with({ selector: '#producersTable' }));
- let producerRows = await producersTable.getRows();
- expect(producerRows.length).toEqual(2);
- producerRows.forEach(row => {
- row.getCellTextByColumnName().then(values => {
- expect(expectedProducerRows).toContain(jasmine.objectContaining(values));
- });
+ it('should contain producers table with correct columns', async () => {
+ setServiceSpy();
+
+ let producersTable = await loader.getHarness(MatTableHarness.with({ selector: '#producersTable' }));
+ let headerRow = (await producersTable.getHeaderRows())[0];
+ let headers = await headerRow.getCellTextByColumnName();
+ expect(headers).toEqual({ id: 'Producer ID', types: 'Producer types', status: 'Producer status' });
+ });
+
+ it('should set correct dark mode from UIService', () => {
+ setServiceSpy();
+ component.ngOnInit();
+ expect(component.darkMode).toBeTruthy();
+
+ const uiService: UiService = TestBed.inject(UiService);
+ uiService.darkModeState.next(false);
+ fixture.detectChanges();
+ expect(component.darkMode).toBeFalsy();
});
});
- describe('should display default values for non required properties', () => {
- it('producer defaults', async () => {
- const producerMissingProperties = {
- ei_producer_id: 'producer1'
- } as EIProducer;
- const producers: EIProducer[] = [producerMissingProperties];
- producerDataSourceSpy.eiProducersSubject.and.returnValue(of(producers));
+ describe('#producersTable', () => {
+
+ const expectedProducer1Row = { id: 'producer1', types: 'type1,type2', status: 'ENABLED' };
+
+ it('should contain data after initialization', async () => {
+ setServiceSpy();
component.ngOnInit();
+ const expectedProducerRows = [
+ expectedProducer1Row,
+ { id: 'producer2', types: 'type2,type3', status: 'DISABLED' }
+ ];
+ let producersTable = await loader.getHarness(MatTableHarness.with({ selector: '#producersTable' }));
+ let producerRows = await producersTable.getRows();
+ expect(producerRows.length).toEqual(2);
+ producerRows.forEach(row => {
+ row.getCellTextByColumnName().then(values => {
+ expect(expectedProducerRows).toContain(jasmine.objectContaining(values));
+ });
+ });
+ });
+ it('should display defaults values for non required properties', async () => {
+ let eiServiceSpy = TestBed.inject(EIService) as jasmine.SpyObj<EIService>;
+
+ eiServiceSpy.getProducerIds.and.returnValue(of(['producer1']));
+ eiServiceSpy.getProducer.and.returnValues(of({} as ProducerRegistrationInfo));
+ eiServiceSpy.getProducerStatus.and.returnValues(of({} as ProducerStatus));
+
+ component.ngOnInit();
const expectedProducerRow = { id: 'producer1', types: '< No types >', status: '< No status >' };
let producersTable = await loader.getHarness(MatTableHarness.with({ selector: '#producersTable' }));
let producerRows = await producersTable.getRows();
expect(await producerRows[0].getCellTextByColumnName()).toEqual(expectedProducerRow);
});
- });
- it('filtering', async () => {
- const expectedProducer1Row = { id: 'producer1', types: 'type1,type2', status: 'ENABLED' };
- component.ngOnInit();
- let producersTable = await loader.getHarness(MatTableHarness.with({ selector: '#producersTable' }));
-
- let idFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#producerIdFilter' }));
- await idFilterInput.setValue("1");
- let producerRows = await producersTable.getRows();
- expect(producerRows.length).toEqual(1);
- expect(await producerRows[0].getCellTextByColumnName()).toEqual(expectedProducer1Row);
-
- idFilterInput.setValue('');
- let typesFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#producerTypesFilter' }));
- await typesFilterInput.setValue("1");
- producerRows = await producersTable.getRows();
- expect(producerRows.length).toEqual(1);
- expect(await producerRows[0].getCellTextByColumnName()).toEqual(expectedProducer1Row);
- await typesFilterInput.setValue("2");
- producerRows = await producersTable.getRows();
- expect(producerRows.length).toEqual(2);
-
- typesFilterInput.setValue('');
- let statusFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#producerStatusFilter' }));
- await statusFilterInput.setValue("enabled");
- producerRows = await producersTable.getRows();
- expect(producerRows.length).toEqual(1);
- expect(await producerRows[0].getCellTextByColumnName()).toEqual(expectedProducer1Row);
+ it('filtering', async () => {
+ setServiceSpy();
+ component.ngOnInit();
+ let producersTable = await loader.getHarness(MatTableHarness.with({ selector: '#producersTable' }));
+
+ let idFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#producerIdFilter' }));
+ await idFilterInput.setValue("1");
+ let producerRows = await producersTable.getRows();
+ expect(producerRows.length).toEqual(1);
+ expect(await producerRows[0].getCellTextByColumnName()).toEqual(expectedProducer1Row);
+
+ idFilterInput.setValue('');
+ let typesFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#producerTypesFilter' }));
+ await typesFilterInput.setValue("1");
+ producerRows = await producersTable.getRows();
+ expect(producerRows.length).toEqual(1);
+ expect(await producerRows[0].getCellTextByColumnName()).toEqual(expectedProducer1Row);
+ await typesFilterInput.setValue("2");
+ producerRows = await producersTable.getRows();
+ expect(producerRows.length).toEqual(2);
+
+ typesFilterInput.setValue('');
+ let statusFilterInput = await loader.getHarness(MatInputHarness.with({ selector: '#producerStatusFilter' }));
+ await statusFilterInput.setValue("enabled");
+ producerRows = await producersTable.getRows();
+ expect(producerRows.length).toEqual(1);
+ expect(await producerRows[0].getCellTextByColumnName()).toEqual(expectedProducer1Row);
+ });
+
+ describe('#sorting', () => {
+
+ it('should verify sort functionality on the table', async () => {
+ setServiceSpy();
+ const sort = await loader.getHarness(MatSortHarness);
+ let headers = await sort.getSortHeaders({ sortDirection: '' });
+ expect(headers.length).toBe(3);
+
+ await headers[0].click();
+ expect(await headers[0].isActive()).toBe(true);
+ expect(await headers[0].getSortDirection()).toBe('asc');
+
+ await headers[0].click();
+ expect(await headers[0].getSortDirection()).toBe('desc');
+
+ });
+
+ it('should sort table asc and desc by first header', async () => {
+ setServiceSpy();
+ const sort = await loader.getHarness(MatSortHarness);
+ let producersTable = await loader.getHarness(MatTableHarness.with({ selector: '#producersTable' }));
+ const firstHeader = (await sort.getSortHeaders())[0];
+ expect(await firstHeader.getSortDirection()).toBe('');
+
+ await firstHeader.click();
+ expect(await firstHeader.getSortDirection()).toBe('asc');
+ let prodRows = await producersTable.getRows();
+ prodRows = await producersTable.getRows();
+ expect(await prodRows[0].getCellTextByColumnName()).toEqual(expectedProducer1Row);
+
+ await firstHeader.click();
+ expect(await firstHeader.getSortDirection()).toBe('desc');
+ prodRows = await producersTable.getRows();
+ expect(await prodRows[prodRows.length - 1].getCellTextByColumnName()).toEqual(expectedProducer1Row);
+ });
+ });
});
});
+
+function setServiceSpy() {
+ let producerRegInfo1 = {
+ supported_ei_types: ['type1', 'type2']
+ } as ProducerRegistrationInfo;
+ let producerRegInfo2 = {
+ supported_ei_types: ['type2', 'type3']
+ } as ProducerRegistrationInfo;
+ let producerStatus1 = {
+ operational_state: OperationalState.ENABLED
+ } as ProducerStatus;
+ let producerStatus2 = {
+ operational_state: OperationalState.DISABLED
+ } as ProducerStatus;
+
+ let eiServiceSpy = TestBed.inject(EIService) as jasmine.SpyObj<EIService>;
+
+ eiServiceSpy.getProducerIds.and.returnValue(of(['producer1', 'producer2']));
+ eiServiceSpy.getProducer.and.returnValues(of(producerRegInfo1), of(producerRegInfo2));
+ eiServiceSpy.getProducerStatus.and.returnValues(of(producerStatus1), of(producerStatus2));
+}
+
+
* limitations under the License.
* ========================LICENSE_END===================================
*/
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, ViewChild } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
-import { Sort } from '@angular/material/sort';
+import { MatSort, Sort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
+import { forkJoin, of } from 'rxjs';
+import { BehaviorSubject } from 'rxjs/BehaviorSubject';
+import { mergeMap, finalize, catchError } from 'rxjs/operators';
+import { EIService } from 'src/app/services/ei/ei.service';
import { EIProducer } from '../../interfaces/ei.types';
import { UiService } from '../../services/ui/ui.service';
-import { EIProducerDataSource } from '../ei-producer.datasource';
@Component({
selector: 'nrcp-producers-list',
styleUrls: ['./producers-list.component.scss']
})
export class ProducersListComponent implements OnInit {
- darkMode: boolean;
+
+ @ViewChild(MatSort) sort: MatSort;
+
producersDataSource: MatTableDataSource<EIProducer> = new MatTableDataSource<EIProducer>();
producerForm: FormGroup;
+ darkMode: boolean;
+
+ private loadingSubject = new BehaviorSubject<boolean>(false);
+ private producerSubject = new BehaviorSubject<EIProducer[]>([]);
+ public loading$ = this.loadingSubject.asObservable();
constructor(
- private eiProducersDataSource: EIProducerDataSource,
+ private eiSvc: EIService,
private ui: UiService) {
this.producerForm = new FormGroup({
}
ngOnInit(): void {
- this.refresh();
+ this.loadProducers();
+ this.producerSubject.subscribe((data) => {
+ this.producersDataSource = new MatTableDataSource<EIProducer>(data);
+ //this.producersDataSource.data = data;
+ });
this.producerForm.valueChanges.subscribe(value => {
const filter = { ...value, ei_producer_id: value.ei_producer_id.trim().toLowerCase() } as string;
});
}
+ ngOnDestroy() {
+ if (!this.producerSubject) this.producerSubject.unsubscribe();
+ if (!this.loadingSubject) this.loadingSubject.unsubscribe();
+ if (!this.ui.darkModeState) this.ui.darkModeState.unsubscribe();
+ }
+
isDataIncluding(data: string, filter: string): boolean {
return !filter || data.toLowerCase().includes(filter);
}
return '< No status >';
}
- refresh() {
- this.eiProducersDataSource.loadProducers();
- this.eiProducersDataSource.eiProducersSubject().subscribe((data) => {
- this.producersDataSource.data = data;
+ public eiProducers(): EIProducer[] {
+ return this.producerSubject.value;
+ }
+
+ loadProducers() {
+ this.loadingSubject.next(true);
+ let producers = [];
+
+ this.eiSvc.getProducerIds().pipe(
+ mergeMap(prodIds =>
+ forkJoin(prodIds.map(id => {
+ return forkJoin([
+ of(id),
+ this.eiSvc.getProducer(id),
+ this.eiSvc.getProducerStatus(id)
+ ])
+ })
+ )),
+ finalize(() => this.loadingSubject.next(false)),
+ ).subscribe(result => {
+ producers = result.map(producer => {
+ let eiProducer = <EIProducer>{};
+ eiProducer.ei_producer_id = producer[0];
+ if (producer[1].supported_ei_types) {
+ eiProducer.ei_producer_types = producer[1].supported_ei_types;
+ }
+ if (producer[2].operational_state) {
+ eiProducer.status = producer[2].operational_state.toString();
+ }
+ return eiProducer;
+ });
+ this.producerSubject.next(producers);
+ }, err => {
+ console.error("Subscribe function error:" + err);
});
}
}