2 * ========================LICENSE_START=================================
5 * Copyright (C) 2021 Nordix Foundation
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ========================LICENSE_END===================================
20 import { Component, OnInit, ViewChild } from "@angular/core";
21 import { FormControl, FormGroup } from "@angular/forms";
22 import { MatPaginator } from "@angular/material/paginator";
23 import { Sort } from "@angular/material/sort";
24 import { MatTableDataSource } from "@angular/material/table";
31 import { BehaviorSubject } from "rxjs/BehaviorSubject";
38 } from "rxjs/operators";
39 import { EIJob } from "@interfaces/ei.types";
40 import { EIService } from "@services/ei/ei.service";
41 import { UiService } from "@services/ui/ui.service";
43 export interface Job {
53 selector: "nrcp-jobs-list",
54 templateUrl: "./jobs-list.component.html",
55 styleUrls: ["./jobs-list.component.scss"],
57 export class JobsListComponent implements OnInit {
58 @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
59 jobsDataSource: MatTableDataSource<Job>;
63 private jobsSubject$ = new BehaviorSubject<Job[]>([]);
64 private refresh$ = new BehaviorSubject("");
65 private loadingSubject$ = new BehaviorSubject<boolean>(false);
66 private polling$ = new BehaviorSubject<boolean>(true);
67 public loading$ = this.loadingSubject$.asObservable();
68 subscription: Subscription;
69 checked: boolean = false;
71 constructor(private eiSvc: EIService, private ui: UiService) {
72 this.jobForm = new FormGroup({
73 jobId: new FormControl(""),
74 typeId: new FormControl(""),
75 owner: new FormControl(""),
76 targetUri: new FormControl(""),
77 prodId: new FormControl(""),
82 this.subscription = this.dataSubscription();
84 this.jobsSubject$.subscribe((data) => {
85 this.jobsDataSource = new MatTableDataSource<Job>(data);
86 this.jobsDataSource.paginator = this.paginator;
88 this.jobsDataSource.filterPredicate = ((data: Job, filter) => {
89 let searchTerms = JSON.parse(filter);
91 this.isDataIncluding(data.targetUri, searchTerms.targetUri) &&
92 this.isDataIncluding(data.jobId, searchTerms.jobId) &&
93 this.isDataIncluding(data.owner, searchTerms.owner) &&
94 this.isDataIncluding(data.typeId, searchTerms.typeId) &&
95 this.isDataIncluding(data.prodId, searchTerms.prodId)
97 }) as (data: Job, filter: any) => boolean;
100 this.jobForm.valueChanges.subscribe((value) => {
101 this.jobsDataSource.filter = JSON.stringify(value);
104 this.ui.darkModeState.subscribe((isDark) => {
105 this.darkMode = isDark;
109 dataSubscription(): Subscription {
111 const jobs$ = this.eiSvc.getProducerIds().pipe(
112 tap((data) => (prodId = data)),
113 mergeMap((prodIds) =>
114 forkJoin(prodIds.map((id) => this.eiSvc.getJobsForProducer(id)))
116 finalize(() => this.loadingSubject$.next(false))
119 const refreshedJobs$ = this.refresh$
121 switchMap((_) => timer(0, 10000).pipe(
123 this.loadingSubject$.next(true);
125 switchMap((_) => jobs$),
126 map((response) => this.extractJobs(prodId, response))
131 return this.polling$.pipe(
133 return p ? refreshedJobs$ : EMPTY;
139 this.subscription.unsubscribe();
143 this.jobForm.get("jobId").setValue("");
144 this.jobForm.get("typeId").setValue("");
145 this.jobForm.get("owner").setValue("");
146 this.jobForm.get("targetUri").setValue("");
147 this.jobForm.get("prodId").setValue("");
150 sortJobs(sort: Sort) {
151 const data = this.jobsDataSource.data;
152 data.sort((a: Job, b: Job) => {
153 const isAsc = sort.direction === "asc";
154 switch (sort.active) {
156 return this.compare(a.jobId, b.jobId, isAsc);
158 return this.compare(a.typeId, b.typeId, isAsc);
160 return this.compare(a.owner, b.owner, isAsc);
162 return this.compare(a.targetUri, b.targetUri, isAsc);
164 return this.compare(a.prodId, b.prodId, isAsc);
169 this.jobsDataSource.data = data;
172 stopPolling(checked){
173 this.polling$.next(checked);
176 compare(a: any, b: any, isAsc: boolean) {
177 return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
180 stopSort(event: any) {
181 event.stopPropagation();
184 isDataIncluding(data: string, filter: string): boolean {
185 const transformedFilter = filter.trim().toLowerCase();
186 return data.toLowerCase().includes(transformedFilter);
189 getJobTypeId(eiJob: Job): string {
193 return "< No type >";
196 getJobOwner(eiJob: Job): string {
200 return "< No owner >";
203 public jobs(): Job[] {
204 return this.jobsSubject$.value;
207 private extractJobs(prodId: number[], res: EIJob[][]) {
210 prodId.forEach((element, index) => {
211 let jobs = res[index];
212 jobList = jobList.concat(jobs.map((job) => this.createJob(element, job)));
214 this.jobsSubject$.next(jobList);
218 createJobList(prodId: any[], result: EIJob[][]) {
220 prodId.forEach((element, index) => {
221 let jobs = result[index];
222 jobList = jobList.concat(jobs.map((job) => this.createJob(element, job)));
227 createJob(element: any, job: EIJob): any {
229 eiJob.jobId = job.ei_job_identity;
230 eiJob.typeId = job.ei_type_identity;
231 eiJob.owner = job.owner;
232 eiJob.targetUri = job.target_uri;
233 eiJob.prodId = element;
238 this.refresh$.next("");