"@angular/platform-browser-dynamic": "^8.2.14",
"@angular/router": "^8.2.14",
"@fortawesome/fontawesome-free": "^5.12.0",
- "@kubernetes/client-node": "^0.10.3",
+ "@kubernetes/client-node": "^0.12.3",
"@material/radio": "^2.3.0",
"@types/chart.js": "^2.9.11",
"@types/uuid": "^7.0.3",
import { Routes, RouterModule } from '@angular/router';
import { MainComponent } from './main/main.component';
import { PolicyControlComponent } from './policy-control/policy-control.component';
+import { EICoordinatorComponent } from './ei-coordinator/ei-coordinator.component';
const routes: Routes = [
{ path: '', component: MainComponent },
- { path: 'policy', component: PolicyControlComponent }
+ { path: 'policy', component: PolicyControlComponent },
+ { path: 'ei-coordinator', component: EICoordinatorComponent }
];
@NgModule({
import { SidenavListComponent } from './navigation/sidenav-list/sidenav-list.component';
import { UiService } from './services/ui/ui.service';
import { CookieModule } from 'ngx-cookie';
+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';
+
@NgModule({
declarations: [
ConfirmDialogComponent,
+ EICardComponent,
+ EICoordinatorComponent,
ErrorDialogComponent,
FooterComponent,
MainComponent,
PolicyInstanceComponent,
PolicyInstanceDialogComponent,
ControlpanelComponent,
- SidenavListComponent
+ SidenavListComponent,
+ NodeModulesComponent
],
imports: [
BrowserModule,
--- /dev/null
+<!--
+========================LICENSE_START=================================
+O-RAN-SC
+%%
+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===================================
+-->
+
+<h3 class="rd-global-page-title">Enrichment Information Coordinator</h3>
+
+<br>
+<h4>Jobs</h4>
+<table mat-table EIJobTable [dataSource]="eiJobsDataSource" [ngClass]="{'table-dark': darkMode}" matSort
+ multiTemplateDataRows class="ei-coordinator-table mat-elevation-z8">
+ <ng-container matColumnDef="id">
+ <th mat-header-cell *matHeaderCellDef> Job ID </th>
+ <td mat-cell *matCellDef="let eiJob"> {{this.getDisplayName(eiJob)}} </td>
+ </ng-container>
+ <!--ng-container matColumnDef="data">
+ <th mat-header-cell *matHeaderCellDef> Job data </th>
+ <td mat-cell *matCellDef="let eiJob"> {{this.getEIJobInfo(eiJob)}} </td>
+ </ng-container-->
+ <ng-container matColumnDef="typeId">
+ <th mat-header-cell *matHeaderCellDef> Type ID </th>
+ <td mat-cell *matCellDef="let eiJob"> {{this.getEITypeId(eiJob)}} </td>
+ </ng-container>
+ <ng-container matColumnDef="targetUri">
+ <th mat-header-cell *matHeaderCellDef> Target URI </th>
+ <td mat-cell *matCellDef="let eiJob"> {{this.getTargetUri(eiJob)}} </td>
+ </ng-container>
+ <tr mat-header-row *matHeaderRowDef="['id', 'typeId', 'targetUri']"></tr>
+ <tr mat-row *matRowDef="let row; columns: ['id', 'typeId', 'targetUri'];"></tr>
+</table>
+
+<br>
+<h4>Producers</h4>
+<table mat-table EIProducerTable [dataSource]="eiProducersDataSource" [ngClass]="{'table-dark': darkMode}" matSort
+ multiTemplateDataRows class="ei-coordinator-table mat-elevation-z8">
+ <ng-container matColumnDef="id">
+ <th mat-header-cell *matHeaderCellDef> Producer ID </th>
+ <td mat-cell *matCellDef="let eiProducer"> {{this.getEIProducerId(eiProducer)}} </td>
+ </ng-container>
+ <ng-container matColumnDef="type">
+ <th mat-header-cell *matHeaderCellDef> Producer type </th>
+ <td mat-cell *matCellDef="let eiProducer"> {{this.getEIProducerTypes(eiProducer)}} </td>
+ </ng-container>
+ <ng-container matColumnDef="status">
+ <th mat-header-cell *matHeaderCellDef> Producer status </th>
+ <td mat-cell *matCellDef="let eiProducer"> {{this.getEIProducerStatus(eiProducer)}} </td>
+ </ng-container>
+ <tr mat-header-row *matHeaderRowDef="['id', 'type', 'status']"></tr>
+ <tr mat-row *matRowDef="let row; columns: ['id', 'type', 'status'];"></tr>
+</table>
\ No newline at end of file
--- /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===================================
+ */
+
+.spinner-container {
+ height: 100px;
+ width: 100px;
+}
+
+.spinner-container mat-spinner {
+ margin: 0 auto 0 auto;
+}
+
+.ei-coordinator-table {
+ width: 100%;
+ min-height: 150px;
+ margin-top: 10px;
+ margin-bottom: 10px;
+ background-color: transparent;
+}
+
+.action-cell {
+ display: flex;
+ justify-content: flex-end;
+}
+
+.display-none {
+ display: none;
+}
\ No newline at end of file
--- /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 { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EICoordinatorComponent } from './ei-coordinator.component';
+
+describe('EICoordinatorComponent', () => {
+ let component: EICoordinatorComponent;
+ let fixture: ComponentFixture<EICoordinatorComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ EICoordinatorComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(EICoordinatorComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
--- /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 { Component, OnInit, ViewChild } 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 { 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 { UiService } from '../services/ui/ui.service';
+
+class EIJobInfo {
+ constructor(public eiJob: EIJob) { }
+
+ isExpanded: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
+}
+
+@Component({
+ selector: 'rd-ei-coordinator',
+ templateUrl: './ei-coordinator.component.html',
+ styleUrls: ['./ei-coordinator.component.scss'],
+ animations: [
+ trigger('detailExpand', [
+ state('collapsed, void', style({ height: '0px', minHeight: '0', display: 'none' })),
+ state('expanded', style({ height: '*' })),
+ transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
+ transition('expanded <=> void', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)'))
+ ]),
+ ],
+})
+export class EICoordinatorComponent implements OnInit {
+
+
+ eiJobsDataSource: EIJobDataSource;
+ eiProducersDataSource: EIProducerDataSource;
+ @ViewChild(MatSort, { static: true }) sort: MatSort;
+
+ eiJobInfo = new Map<string, EIJobInfo>();
+ darkMode: boolean;
+
+ constructor(
+ private eiSvc: EIService,
+ private dialog: MatDialog,
+ private notificationService: NotificationService,
+ private ui: UiService) { }
+
+ 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.ui.darkModeState.subscribe((isDark) => {
+ this.darkMode = isDark;
+ });
+ }
+
+ toggleListInstances(eiJob: EIJob): void {
+ const info = this.getEIJobInfo(eiJob);
+ info.isExpanded.next(!info.isExpanded.getValue());
+ }
+
+ getEIJobInfo(eiJob: EIJob): EIJobInfo {
+ let info: EIJobInfo = this.eiJobInfo.get(eiJob.ei_job_data);
+ if (!info) {
+ info = new EIJobInfo(eiJob);
+ this.eiJobInfo.set(eiJob.ei_job_data, info);
+ }
+ return info;
+ }
+
+ getDisplayName(eiJob: EIJob): string {
+ if (eiJob.ei_job_identity) {
+ return eiJob.ei_job_identity;
+ }
+ return '< No id >';
+ }
+
+ getEITypeId(eiJob: EIJob): string {
+ if (eiJob.ei_type_identity){
+ return eiJob.ei_type_identity;
+ }
+ return '< No type >';
+ }
+
+ getTargetUri(eiJob: EIJob): string {
+ if (eiJob.target_uri){
+ return eiJob.target_uri;
+ }
+ return '< No target URI >';
+ }
+
+ isInstancesShown(eiJob: EIJob): boolean {
+ return this.getEIJobInfo(eiJob).isExpanded.getValue();
+ }
+
+ getExpandedObserver(eiJob: EIJob): Observable<boolean> {
+ return this.getEIJobInfo(eiJob).isExpanded.asObservable();
+ }
+
+ getEIProducerId(eiProducer: EIProducer): string {
+ if (eiProducer.ei_producer_id){
+ return eiProducer.ei_producer_id;
+ }
+ return '< No id>';
+ }
+
+ getEIProducerTypes(eiProducer: EIProducer): string[] {
+ if (eiProducer.ei_producer_types){
+ return eiProducer.ei_producer_types;
+ }
+ return ['< No types >'];
+ }
+
+ getEIProducerStatus(eiProducer: EIProducer): string {
+ if (eiProducer.status){
+ return eiProducer.status;
+ }
+ return '< No status >';
+ }
+}
--- /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 { 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 { EIJob } from '../interfaces/ei.jobs';
+import { EIService } from '../services/ei/ei.service';
+import { NotificationService } from '../services/ui/notification.service';
+
+export class EIJobDataSource extends DataSource<EIJob> {
+
+ private eiJobSubject = new BehaviorSubject<EIJob[]>([]);
+
+ private loadingSubject = new BehaviorSubject<boolean>(false);
+
+ public loading$ = this.loadingSubject.asObservable();
+
+ public rowCount = 1; // hide footer during intial load
+
+ constructor(
+ private eiSvc: EIService,
+ public sort: MatSort,
+ private notificationService: NotificationService) {
+ super();
+ }
+
+ loadTable() {
+ this.loadingSubject.next(true);
+ this.eiSvc.getEIJobs()
+ .pipe(
+ catchError((her: HttpErrorResponse) => {
+ this.notificationService.error('Failed to get EI jobs: ' + her.error);
+ return of([]);
+ }),
+ finalize(() => this.loadingSubject.next(false))
+ )
+ .subscribe((instances: EIJob[]) => {
+ console.log("Jobs: " + instances);
+ this.rowCount = instances.length;
+ this.eiJobSubject.next(instances);
+ });
+ }
+
+ connect(): Observable<EIJob[]> {
+ const dataMutations = [
+ this.eiJobSubject.asObservable(),
+ this.sort.sortChange
+ ];
+ return merge(...dataMutations).pipe(map(() => {
+ return this.getSortedData([...this.eiJobSubject.getValue()]);
+ }));
+ }
+
+ disconnect(): void {
+ this.eiJobSubject.complete();
+ this.loadingSubject.complete();
+ }
+
+ private getSortedData(data: EIJob[]) {
+ if (!this.sort || !this.sort.active || this.sort.direction === '') {
+ return data;
+ }
+
+ 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);
+ default: return 0;
+ }
+ });
+ }
+}
+
+function compare(a: string, b: string, isAsc: boolean) {
+ return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
+}
--- /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 { 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 { EIProducer } from '../interfaces/ei.jobs';
+import { EIService } from '../services/ei/ei.service';
+import { NotificationService } from '../services/ui/notification.service';
+
+export class EIProducerDataSource extends DataSource<EIProducer> {
+
+ private producerSubject = new BehaviorSubject<EIProducer[]>([]);
+
+ private loadingSubject = new BehaviorSubject<boolean>(false);
+
+ public loading$ = this.loadingSubject.asObservable();
+
+ public rowCount = 1; // hide footer during intial load
+
+ constructor(
+ private eiSvc: EIService,
+ public sort: MatSort,
+ private notificationService: NotificationService) {
+ super();
+ }
+
+ loadTable() {
+ this.loadingSubject.next(true);
+ this.eiSvc.getEIProducers()
+ .pipe(
+ catchError((her: HttpErrorResponse) => {
+ this.notificationService.error('Failed to get producers: ' + her.error);
+ return of([]);
+ }),
+ finalize(() => this.loadingSubject.next(false))
+ )
+ .subscribe((prods: EIProducer[]) => {
+ console.log("Producers: " + prods);
+ this.rowCount = prods.length;
+ this.producerSubject.next(prods);
+ });
+ }
+
+ connect(): Observable<EIProducer[]> {
+ const dataMutations = [
+ this.producerSubject.asObservable(),
+ this.sort.sortChange
+ ];
+ return merge(...dataMutations).pipe(map(() => {
+ return this.getSortedData([...this.producerSubject.getValue()]);
+ }));
+ }
+
+ disconnect(): void {
+ this.producerSubject.complete();
+ this.loadingSubject.complete();
+ }
+
+ private getSortedData(data: EIProducer[]) {
+ if (!this.sort || !this.sort.active || this.sort.direction === '') {
+ return data;
+ }
+
+ 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);
+ default: return 0;
+ }
+ });
+ }
+}
+
+function compare(a: string, b: string, isAsc: boolean) {
+ return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
+}
--- /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 { 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 { EIService } from '../services/ei/ei.service';
+import { EIType } from '../interfaces/ei.jobs';
+import { NotificationService } from '../services/ui/notification.service';
+
+export class EITypeDataSource extends DataSource<EIType> {
+
+ private eiTypeSubject = new BehaviorSubject<EIType[]>([]);
+
+ private loadingSubject = new BehaviorSubject<boolean>(false);
+
+ public loading$ = this.loadingSubject.asObservable();
+
+ public rowCount = 1; // hide footer during intial load
+
+ constructor(private eiSvc: EIService,
+ private sort: MatSort,
+ private notificationService: NotificationService) {
+ super();
+ }
+
+ loadTable() {
+ this.loadingSubject.next(true);
+ this.eiSvc.getEITypes()
+ .pipe(
+ catchError((her: HttpErrorResponse) => {
+ this.notificationService.error('Failed to get EI types: ' + her.statusText + ', ' + her.error);
+ return of([]);
+ }),
+ finalize(() => this.loadingSubject.next(false))
+ )
+ .subscribe((types: EIType[]) => {
+ console.log("Types: " + types);
+ this.rowCount = types.length;
+ this.eiTypeSubject.next(types);
+ });
+ }
+
+ connect(collectionViewer: CollectionViewer): Observable<EIType[]> {
+ const dataMutations = [
+ this.eiTypeSubject.asObservable(),
+ this.sort.sortChange
+ ];
+ return merge(...dataMutations).pipe(map(() => {
+ return this.getSortedData([...this.eiTypeSubject.getValue()]);
+ }));
+ }
+
+ disconnect(collectionViewer: CollectionViewer): void {
+ this.eiTypeSubject.complete();
+ this.loadingSubject.complete();
+ }
+
+ private getSortedData(data: EIType[]) {
+ if (!this.sort.active || this.sort.direction === '') {
+ return data;
+ }
+
+ return data.sort((a, b) => {
+ const isAsc = this.sort.direction === 'asc';
+ switch (this.sort.active) {
+ case 'eiTypeId': return compare(a.description, b.description, isAsc);
+ default: return 0;
+ }
+ });
+ }
+}
+
+function compare(a: any, b: any, isAsc: boolean) {
+ return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
+}
--- /dev/null
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * 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===================================
+ */
+
+// 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;
+ ei_type_identity: string;
+ target_uri: string;
+ }
+
+ export interface EIType {
+ id: string;
+ description: string;
+ }
+
+ export interface EIProducer {
+ ei_producer_id: string;
+ ei_producer_types: string[];
+ status: string;
+ }
\ No newline at end of file
-->
<div class = "main__container">
<rd-policy-card></rd-policy-card>
+ <rd-ei-card></rd-ei-card>
</div>
<a mat-list-item routerLink="/policy" (click)="onSidenavClose()">
<mat-icon>assignment</mat-icon> <span class="nav-caption">Policy</span>
</a>
+ <a mat-list-item routerLink="/ei-coordinator" (click)="onSidenavClose()">
+ <mat-icon>assignment</mat-icon> <span class="nav-caption">Enrichment Information Coordinator</span>
+</a>
</mat-nav-list>
--- /dev/null
+<p>node-modules works!</p>
--- /dev/null
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NodeModulesComponent } from './node-modules.component';
+
+describe('NodeModulesComponent', () => {
+ let component: NodeModulesComponent;
+ let fixture: ComponentFixture<NodeModulesComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ NodeModulesComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(NodeModulesComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
--- /dev/null
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'rd-node-modules',
+ templateUrl: './node-modules.component.html',
+ styleUrls: ['./node-modules.component.scss']
+})
+export class NodeModulesComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit() {
+ }
+
+}
--- /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 { TestBed } from '@angular/core/testing';
+
+import { EIService } from './ei.service';
+
+describe('PolicyService', () => {
+ beforeEach(() => TestBed.configureTestingModule({}));
+
+ it('should be created', () => {
+ const service: EIService = TestBed.get(EIService);
+ expect(service).toBeTruthy();
+ });
+});
--- /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 { HttpClient } from '@angular/common/http';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+import { EIJob, EIType, EIProducer } from '../../interfaces/ei.jobs';
+import { ControlpanelSuccessTransport } from '../../interfaces/controlpanel.types';
+
+/**
+ * Services for calling the EI endpoints.
+ */
+@Injectable({
+ providedIn: 'root'
+})
+export class EIService {
+
+ private basePath = 'api/enrichment';
+ private eiTypePath = 'eitypes';
+ private eiJobPath = 'eijobs';
+ private eiProducerPath = 'eiproducers';
+
+ private buildPath(...args: any[]) {
+ let result = this.basePath;
+ args.forEach(part => {
+ result = result + '/' + part;
+ });
+ console.log("URL: "+result);
+ return result;
+ }
+
+ constructor(private httpClient: HttpClient) {
+ // injects to variable httpClient
+ }
+
+ /**
+ * Gets version details
+ * @returns Observable that should yield a String
+ */
+ getVersion(): Observable<string> {
+ const url = this.buildPath('version');
+ return this.httpClient.get<ControlpanelSuccessTransport>(url).pipe(
+ // Extract the string here
+ map(res => res['data'])
+ );
+ }
+
+ getEITypes(): Observable<EIType[]> {
+ const url = this.buildPath(this.eiTypePath);
+ return this.httpClient.get<EIType[]>(url);
+ }
+
+ getEIJobs(): Observable<EIJob[]> {
+ const url = this.buildPath(this.eiJobPath);
+ return this.httpClient.get<EIJob[]>(url);
+ }
+
+ getEIProducers(): Observable<EIProducer[]> {
+ const url = this.buildPath(this.eiProducerPath);
+ return this.httpClient.get<EIProducer[]>(url);
+ }
+}
--- /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===================================
+ -->
+<div class="ei__card" routerLink="/ei-coordinator" [ngClass]="{'add__card-dark': darkMode}">
+ <div class="header__container">
+ <span class="card__title">Enrichment Information Coordinator</span><br><br><br>
+ <div style="color: black; size: 1em; text-align: center">
+ <mat-icon>build</mat-icon>Config</div>
+
+
+ </div>
+ <div class="body__container">
+ <img src="../../../assets/oran-logo.png" width="250px"/>
+ </div>
+</div>
--- /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===================================
+ */
+.ei__card {
+ background-color: #ffffff;
+ box-shadow: 0 0 2rem rgba(0, 0, 255, 0.1);
+ display: grid;
+ grid-template-columns: 1fr;
+ grid-template-rows: 1fr 1fr;
+ padding: 2rem;
+ margin: 2rem;
+ width: 19rem;
+ height: 30rem;
+ justify-items: center;
+ cursor: pointer;
+ border-radius: 1.75rem;
+ animation: fadein 1.25s ease-in-out 0ms 1;
+ color: #443282;
+}
+
+.add__card-dark {
+ background: linear-gradient(to bottom, rgb(78, 78, 129), rgb(45, 44, 61));
+ color: white;
+}
+
+.card__title {
+ text-transform: uppercase;
+ letter-spacing: 0.1rem;
+}
+
+.body__container {
+ align-self: end;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-flow: column;
+}
+
+.add__icon {
+ width: 10rem;
+ margin-bottom: 1.15rem;
+}
\ No newline at end of file
--- /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 {async, ComponentFixture, TestBed} from '@angular/core/testing';
+
+import {EICardComponent} from './ei-card.component';
+
+describe('EICardComponent', () => {
+ let component: EICardComponent;
+ let fixture: ComponentFixture<EICardComponent>;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [EICardComponent]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(EICardComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
--- /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 { Component, OnDestroy, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+import { UiService } from '../../services/ui/ui.service';
+
+@Component({
+ selector: 'rd-ei-card',
+ templateUrl: './ei-card.component.html',
+ styleUrls: ['./ei-card.component.scss']
+})
+export class EICardComponent implements OnInit, OnDestroy {
+ darkMode: boolean;
+
+ constructor(public router: Router, private ui: UiService) { }
+
+ ngOnInit() {
+ this.ui.darkModeState.subscribe((isDark) => {
+ this.darkMode = isDark;
+ });
+ }
+
+ ngOnDestroy() { }
+
+ openDetails() {
+ this.router.navigateByUrl('../../ei-coordinator');
+ }
+
+}