From 35ff615bc6416aa7cd6fd63dac5e02dd456336fb Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Fri, 23 Sep 2022 10:05:56 +0200
Subject: [PATCH] feature edit dataset

---
 src/app/app-routing.module.ts                 |   2 +
 src/app/app.module.ts                         |   2 +
 .../datasets/services/dataset-crud.service.ts |   2 +-
 src/app/edition/edition.component.html        | 152 ++++++++++++++++
 src/app/edition/edition.component.scss        |   8 +
 src/app/edition/edition.component.spec.ts     |  25 +++
 src/app/edition/edition.component.ts          | 168 ++++++++++++++++++
 src/app/edition/service/edit.service.ts       |  52 ++++++
 src/app/mapping/class/dataset.ts              |   1 +
 .../feedback-dialog.component.html            |   1 +
 .../feedback-dialog.component.ts              |   4 +-
 src/app/mapping/service/mapping.service.ts    |   2 +-
 .../semantic-enrichment/ConceptsRequest.ts    |   1 +
 src/app/stats/stats.component.html            |   2 +-
 src/app/stats/stats.component.ts              |  64 +++----
 15 files changed, 446 insertions(+), 40 deletions(-)
 create mode 100644 src/app/edition/edition.component.html
 create mode 100644 src/app/edition/edition.component.scss
 create mode 100644 src/app/edition/edition.component.spec.ts
 create mode 100644 src/app/edition/edition.component.ts
 create mode 100644 src/app/edition/service/edit.service.ts

diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 4100ee6b4..895fa509e 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -12,6 +12,7 @@ import { FdpGuard } from './authentication/services/fdp.guard';
 import { RepositoryinfoComponent } from './repositoryinfo/repositoryinfo.component';
 import { PublishApiComponent } from './publishapi/publishapi.component';
 import {SemanticEnrichmentComponent} from './semantic-enrichment/semantic-enrichment.component';
+import {EditionComponent} from './edition/edition.component';
 
 export interface ICustomRoute extends Route {
   name?: string;
@@ -27,6 +28,7 @@ const routes: ICustomRoute[] = [
         { path: 'repositoryinfo', component: RepositoryinfoComponent },
         { path: 'stats', component: StatsComponent },
         { path: 'publishapi', component: PublishApiComponent },
+        { path: 'edit/:id', component: EditionComponent}
       ]
   },
   {path: 'fdpsignin', component: SignupComponent, canActivate: [AuthGuardService]},
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 733dd5f71..f199402fe 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -48,6 +48,7 @@ import { SemanticEnrichmentComponent } from './semantic-enrichment/semantic-enri
 import {MatAutocompleteModule} from '@angular/material/autocomplete';
 import {MatFormFieldModule} from '@angular/material/form-field';
 import { OrderByScorePipe } from './semantic-enrichment/pipes/order-by-score.pipe';
+import { EditionComponent } from './edition/edition.component';
 
 
 
@@ -69,6 +70,7 @@ import { OrderByScorePipe } from './semantic-enrichment/pipes/order-by-score.pip
     CallbackComponent,
     SemanticEnrichmentComponent,
     OrderByScorePipe,
+    EditionComponent,
 
   ],
     imports: [
diff --git a/src/app/datasets/services/dataset-crud.service.ts b/src/app/datasets/services/dataset-crud.service.ts
index b9cb55b1a..7a00f71dd 100644
--- a/src/app/datasets/services/dataset-crud.service.ts
+++ b/src/app/datasets/services/dataset-crud.service.ts
@@ -46,7 +46,7 @@ export class DatasetCrudService {
     httpOptions.append('Content-Type', 'application/rdf+xml');
     httpOptions.append('Accept', 'application/rdf+xml');
     httpOptions.append('Authorization', `Bearer ${this.smartHarvesterToken}`)
-    let url = `${SMARTHARVESTER_API}/harvester/api/transform?url=${xmlUrl}&catalogId=${catalogID}`;
+    const url = `${SMARTHARVESTER_API}/harvester/api/mapping?url=${xmlUrl}&catalogId=${catalogID}`;
 
     const myInit = { method: 'GET', headers: httpOptions, responseType: 'text' };
     const myRequest = new Request(url, myInit);
diff --git a/src/app/edition/edition.component.html b/src/app/edition/edition.component.html
new file mode 100644
index 000000000..a648b16fa
--- /dev/null
+++ b/src/app/edition/edition.component.html
@@ -0,0 +1,152 @@
+<ng-template #dialog let-data let-ref="dialogRef">
+  <nb-card>
+    <nb-card-body>{{ messageError }}</nb-card-body>
+    <nb-card-footer>
+      <button nbButton (click)="getDatasetByCatalogId();ref.close()">Retry</button>
+      <button nbButton (click)="ref.close()">Close</button>
+    </nb-card-footer>
+  </nb-card>
+</ng-template>
+
+<mat-autocomplete #auto="matAutocomplete" [displayWith]="viewHandle" (optionSelected)="setIri($event)">
+  <mat-option
+    *ngFor="let option of filteredOptions | async"
+    [value]="option">
+    {{option.source.document.label}}
+  </mat-option>
+</mat-autocomplete>
+
+<ng-template #noConcept>
+  <nb-card>
+    <nb-card-body>
+      <h3>No concepts found...</h3>
+    </nb-card-body>
+  </nb-card>
+</ng-template>
+
+<ng-template #noKeywordsFound>
+  <nb-card>
+    <nb-card-body>
+      <h3>No keywords found...</h3>
+    </nb-card-body>
+  </nb-card>
+</ng-template>
+
+<ng-template #loading xmlns="http://www.w3.org/1999/html">
+  <nb-card size="small" [nbSpinner]="true" nbSpinnerStatus="primary" nbSpinnerSize="giant"></nb-card>
+</ng-template>
+<ng-container *ngIf="!isLoading; else loading">
+  <ng-container *ngFor="let keyword of datasets; let i = index">
+    <nb-accordion>
+      <nb-accordion-item>
+        <nb-accordion-item-header><a href="{{keyword.url}}" target="_blank">{{keyword.title}}</a>
+          <div>
+            <nb-icon icon="checkmark-circle-2-outline" [status]=""></nb-icon>
+          </div>
+        </nb-accordion-item-header>
+
+        <nb-accordion-item-body>
+          <nb-card *ngIf="keyword.keywords.length > 0; else noKeywordsFound" [size]="'tiny'">
+            <nb-card-header>
+              Keyword(s) found
+            </nb-card-header>
+            <nb-list>
+              <nb-list-item *ngFor="let k of keyword.keywords">
+                {{ k }}
+              </nb-list-item>
+            </nb-list>
+          </nb-card>
+
+          <nb-card *ngIf="keyword.conceptIri.length > 0; else noConcept" [size]="'tiny'">
+            <nb-card-header>
+              Concept iri found
+            </nb-card-header>
+            <nb-list>
+              <nb-list-item *ngFor="let k of keyword.conceptIri">
+                {{ k }}
+              </nb-list-item>
+            </nb-list>
+          </nb-card>
+          <nb-card>
+            <nb-card-body>
+              <mat-form-field class="half-width">
+                <input
+                  type="text"
+                  placeholder="enter a value with at least 4 characters"
+                  [(ngModel)]="values[i]"
+                  (ngModelChange)="onModelChange($event)"
+                  matInput
+                  [matAutocomplete]="auto"
+                  (focusin)="setId(keyword.url)">
+
+              </mat-form-field>
+              <div class="mt0-m">
+                <table *ngIf="autocompleteMap.get(keyword.url).length > 0">
+                  <thead style="background-color: #3366ff">
+                  <th></th>
+                  <th class="text-center">label</th>
+                  <th class="text-center">definition</th>
+                  <th class="text-center">synonyms</th>
+                  </thead>
+                  <tbody>
+                  <tr *ngFor="let value of autocompleteMap.get(keyword.url); let i = index ">
+                    <td>
+                      <button nbButton ghost>
+                        <nb-icon icon="trash-2-outline" status="danger"
+                                 (click)="deleteProperty(keyword.url, i)">
+                        </nb-icon>
+                      </button>
+                    </td>
+                    <td class="text-center"><a href="{{value.source.document.iri}}"
+                                               target="_blank">{{ value.source.document.label }}</a></td>
+                    <td class="text-center">{{ value.source.document.description }}</td>
+                    <td class="text-center">{{ value.source.document.synonyms }}</td>
+
+                  </tr>
+                  </tbody>
+                </table>
+              </div>
+            </nb-card-body>
+          </nb-card>
+          <nb-card [size]="'small'" *ngIf="keyword.concepts">
+            <table>
+              <thead style="background-color: #3366ff">
+              <th></th>
+              <th class="text-center">label</th>
+              <th class="text-center">definition</th>
+              <th class="text-center">synonyms</th>
+              <th class="text-center">score</th>
+              </thead>
+              <tbody>
+              <tr *ngFor="let objet of keyword.concepts.results | orderByScore">
+                <td class="text-center">
+                  <nb-checkbox [(checked)]="objet.checked"></nb-checkbox>
+                </td>
+                <td class="text-center"><a href="{{objet.source.document.iri}}"
+                                           target="_blank">{{ objet.source.document.label }}</a></td>
+                <td class="text-center">{{ objet.source.document.description }}</td>
+                <td class="text-center">{{ objet.source.document.synonyms }}</td>
+                <td class="text-center">{{ objet.score | number: '2.2-2' }}</td>
+              </tr>
+              </tbody>
+            </table>
+          </nb-card>
+        </nb-accordion-item-body>
+      </nb-accordion-item>
+    </nb-accordion>
+
+  </ng-container>
+
+
+  <div class="row">
+    <div class="button-center">
+      <button nbButton status="primary" (click)="onSubmit()" [nbSpinner]="loadingPublish" [disabled]="loadingPublish"
+              nbSpinnerStatus="basic">Edit
+      </button>
+    </div>
+  </div>
+</ng-container>
+
+
+
+
diff --git a/src/app/edition/edition.component.scss b/src/app/edition/edition.component.scss
new file mode 100644
index 000000000..98beafa84
--- /dev/null
+++ b/src/app/edition/edition.component.scss
@@ -0,0 +1,8 @@
+.button-center{
+  vertical-align: middle;
+  margin: auto
+}
+
+.half-width {
+  width: 50%;
+}
diff --git a/src/app/edition/edition.component.spec.ts b/src/app/edition/edition.component.spec.ts
new file mode 100644
index 000000000..393a216f5
--- /dev/null
+++ b/src/app/edition/edition.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { EditionComponent } from './edition.component';
+
+describe('EditionComponent', () => {
+  let component: EditionComponent;
+  let fixture: ComponentFixture<EditionComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ EditionComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(EditionComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/edition/edition.component.ts b/src/app/edition/edition.component.ts
new file mode 100644
index 000000000..75d94d5d8
--- /dev/null
+++ b/src/app/edition/edition.component.ts
@@ -0,0 +1,168 @@
+import {Component, OnInit, TemplateRef, ViewChild} from '@angular/core';
+import {ActivatedRoute} from '@angular/router';
+import {EditService} from './service/edit.service';
+import {KeywordResponse} from '../mapping/class/dataset';
+import {Observable, of} from 'rxjs';
+import {Result} from '../semantic-enrichment/ESModel';
+import {map} from 'rxjs/operators';
+import {PostService} from '../semantic-enrichment/services/post.service';
+import {NbDialogService} from '@nebular/theme';
+import {MatAutocompleteSelectedEvent} from '@angular/material/autocomplete';
+import {ConceptsRequest, DataConcept} from '../semantic-enrichment/ConceptsRequest';
+import {FeedbackDialogComponent} from '../mapping/dialog/feedback-dialog/feedback-dialog.component';
+import {MatDialog} from '@angular/material/dialog';
+
+@Component({
+  selector: 'app-edition',
+  templateUrl: './edition.component.html',
+  styleUrls: ['./edition.component.scss']
+})
+export class EditionComponent implements OnInit {
+
+  @ViewChild('dialog') dialog: TemplateRef<any>;
+  param: string;
+  datasets: KeywordResponse[] = [];
+  isLoading: boolean;
+  messageError: string;
+  filteredOptions: Observable<Result[]>;
+  autocompleteMap: Map<string, Result[]> = new Map<string, Result[]>();
+  values: string[] = [];
+  id: string;
+  loadingPublish: boolean;
+
+
+  constructor(private route: ActivatedRoute, private service: EditService,
+              private semanticService: PostService, private dialogService: NbDialogService,
+              private matDialog: MatDialog) {
+
+  }
+
+  ngOnInit(): void {
+    this.getDatasetByCatalogId();
+
+  }
+
+  getDatasetByCatalogId() {
+    this.isLoading = true;
+    this.route.params.subscribe(param => {
+      this.service.getCatalog(param.id).subscribe(
+        (response: KeywordResponse[]) => {
+          this.datasets = response,
+          this.datasets.forEach((resp: KeywordResponse) => {
+            this.autocompleteMap.set(resp.url, []);
+            if (resp.concepts) {
+              resp.concepts.results.forEach((result: Result) => {
+                result.checked = false;
+              });
+            }
+          });
+        },
+        error => {
+          this.isLoading = false;
+          this.messageError = error.message;
+          this.openDialog(this.dialog);
+        },
+        () => this.isLoading = false
+      );
+    });
+  }
+  filter(val: string): Observable<any> {
+    if (val.length > 3) {
+      return this.semanticService.getData(val)
+        .pipe(
+          map((response) => response.results ));
+    }
+    return of([]);
+  }
+
+  openDialog(dialog: TemplateRef<any>) {
+    this.dialogService.open(dialog, {
+      context: {
+      },
+    });
+  }
+
+  viewHandle(value: any) {
+    if (typeof value !== 'string' && typeof value !== 'undefined' && null !== value) {
+      if (value.source ) {
+        return value.source.document.label;
+      }
+    }
+    return value;
+  }
+  onModelChange(value: string) {
+    Promise.resolve(null).then(() => this.filteredOptions = this.filter(value));
+  }
+
+  setId(id: string) {
+    this.id = id;
+  }
+
+  setIri(option: MatAutocompleteSelectedEvent) {
+    const iris = this.autocompleteMap.get(this.id);
+    if (iris) {
+      iris.push(option.option.value);
+    }
+    this.autocompleteMap.set(this.id, iris);
+    console.log(this.autocompleteMap);
+  }
+
+  deleteProperty(datasetKeyword: string, i: number) {
+    const results: Result[] = this.autocompleteMap.get(datasetKeyword);
+    results.splice(i, 1);
+    this.autocompleteMap.set(datasetKeyword, results);
+  }
+
+
+  onSubmit() {
+    const mappingData = new ConceptsRequest();
+    mappingData.fdpToken = this.service.fdpToken;
+    mappingData.dataConcepts = [];
+    this.datasets.forEach((data: KeywordResponse) => {
+      if ((null !== data.concepts && data.concepts.results.filter(e => e.checked).length > 0) ||
+        this.autocompleteMap.get(data.url) && this.autocompleteMap.get(data.url).length > 0) {
+        const concepts = new DataConcept();
+        concepts.url = data.url;
+        concepts.iris = [];
+        if (data.concepts) {
+          data.concepts.results.forEach((result: Result) => {
+            if (result.checked) {
+              concepts.iris.push(result.source.document.iri);
+            }
+          });
+        }
+        if (this.autocompleteMap.get(data.url) && this.autocompleteMap.get(data.url).length > 0) {
+          this.autocompleteMap.get(data.url).forEach((result: Result) => concepts.iris.push(result.source.document.iri));
+        }
+        mappingData.dataConcepts.push(concepts);
+      }
+    });
+
+    console.log(mappingData);
+    const postedDatasets = [];
+    const notPostedDatasets = [];
+    this.loadingPublish = true;
+
+    this.service.editDataset(mappingData).subscribe((resp) => {
+      resp.publishedUrl.forEach(e => postedDatasets.push(e));
+      resp.notPublishedUrl.forEach(e => notPostedDatasets.push(e));
+      this.matDialog.open(FeedbackDialogComponent, {
+        data: {
+          postedMetadatas: postedDatasets,
+          notPostedMetadatas: notPostedDatasets
+        }
+      }).afterClosed().subscribe();
+    },
+      error => {
+        this.loadingPublish = false;
+        this.matDialog.open(FeedbackDialogComponent, {
+          data: {
+            errorMessage: error.message,
+            postedMetadatas: postedDatasets,
+            notPostedMetadatas: notPostedDatasets
+          }
+        });
+      },
+      () => this.loadingPublish = false);
+  }
+}
diff --git a/src/app/edition/service/edit.service.ts b/src/app/edition/service/edit.service.ts
new file mode 100644
index 000000000..abd1f0ea8
--- /dev/null
+++ b/src/app/edition/service/edit.service.ts
@@ -0,0 +1,52 @@
+import { Injectable } from '@angular/core';
+import {TokenStorageService} from '../../authentication/services/token-storage.service';
+import {environment} from '../../../environments/environment';
+import {HttpClient, HttpHeaders} from '@angular/common/http';
+import {MetaModel} from '../../stats/MetaModel';
+import {Observable} from 'rxjs';
+import {KeywordResponse} from '../../mapping/class/dataset';
+import {ConceptsRequest} from '../../semantic-enrichment/ConceptsRequest';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class EditService {
+
+  fdpToken = this.tokenService.getFDPToken();
+  fdpURl = environment.fdpUrl;
+  smartharveserToken = this.tokenService.getToken();
+  smartHarvesterUrl = environment.smartharvesterUrl;
+
+  constructor(private tokenService: TokenStorageService, private http: HttpClient) {
+  }
+
+  getCatalog(catId: string): Observable<KeywordResponse[]> {
+    const httpOptions = {
+      headers: new HttpHeaders({
+        Authorization: 'Bearer ' + this.smartharveserToken
+      })
+    };
+    if (!environment.staging && !environment.production) {
+      this.fdpURl = this.fdpURl.replace(':8080', '');
+    }
+    return this.http.get<KeywordResponse[]>(
+      `${this.smartHarvesterUrl}/harvester/api/catalog/${catId}?baseUrl=${this.fdpURl}&token=${this.fdpToken}`,
+      httpOptions
+    );
+  }
+
+   editDataset(data: ConceptsRequest): Observable<any> {
+    const httpOptionsFDP = {
+      headers: new HttpHeaders({
+        Authorization: 'Bearer ' + this.smartharveserToken,
+        Accept: 'application/json',
+        ContentType: 'application/json'
+      })
+    };
+    if (!environment.staging && !environment.production) {
+      this.fdpURl = this.fdpURl.replace(':8080', '');
+    }
+
+    return this.http.put(`${this.smartHarvesterUrl}/harvester/api/mapping`, data, httpOptionsFDP);
+  }
+}
diff --git a/src/app/mapping/class/dataset.ts b/src/app/mapping/class/dataset.ts
index 9d939c3bb..e35e74671 100644
--- a/src/app/mapping/class/dataset.ts
+++ b/src/app/mapping/class/dataset.ts
@@ -74,6 +74,7 @@ export class KeywordResponse {
   public url: string;
   public title: string;
   public keywords: string[];
+  public conceptIri: string[];
   public concepts: ESModel;
 }
 
diff --git a/src/app/mapping/dialog/feedback-dialog/feedback-dialog.component.html b/src/app/mapping/dialog/feedback-dialog/feedback-dialog.component.html
index be9d5cbb4..abd5b634c 100644
--- a/src/app/mapping/dialog/feedback-dialog/feedback-dialog.component.html
+++ b/src/app/mapping/dialog/feedback-dialog/feedback-dialog.component.html
@@ -3,6 +3,7 @@
         <h3 style="text-align: center;">Feedback: </h3>
     </nb-card-header>
     <nb-card-body>
+      <p *ngIf="data.errorMessage">{{data.errorMessage}}</p>
         <nb-card *ngIf="data.notPostedMetadatas.length > 0">
             <nb-card-body>
                 <p class="error" >An error occurred while publishing the following Datasets: </p>
diff --git a/src/app/mapping/dialog/feedback-dialog/feedback-dialog.component.ts b/src/app/mapping/dialog/feedback-dialog/feedback-dialog.component.ts
index d6b6ecdea..fa3f7644f 100644
--- a/src/app/mapping/dialog/feedback-dialog/feedback-dialog.component.ts
+++ b/src/app/mapping/dialog/feedback-dialog/feedback-dialog.component.ts
@@ -9,10 +9,10 @@ import { NbDialogRef } from '@nebular/theme';
 })
 export class FeedbackDialogComponent implements OnInit {
 
-  
+
 
   constructor(private dialog: MatDialogRef<FeedbackDialogComponent>,
-    @Inject(MAT_DIALOG_DATA) public data: {postedMetadatas: any[], notPostedMetadatas: any[]} ) { }
+    @Inject(MAT_DIALOG_DATA) public data: {errorMessage: string, postedMetadatas: any[], notPostedMetadatas: any[]} ) { }
 
   ngOnInit(): void {
   }
diff --git a/src/app/mapping/service/mapping.service.ts b/src/app/mapping/service/mapping.service.ts
index 32644e2c7..e3097fe84 100644
--- a/src/app/mapping/service/mapping.service.ts
+++ b/src/app/mapping/service/mapping.service.ts
@@ -160,7 +160,7 @@ export class MappingService {
     httpOptions.append('Accept', 'application/json');
     httpOptions.append('Authorization', `Bearer ${this.fds2Token}`);
     const url =
-      `${this.smartHarvesterUrl}/harvester/api/transform/publish?fdpUrl=${this.fdpUrl}&catalogId=${catalogId}&isJsonpath=${isJsonpath}`;
+      `${this.smartHarvesterUrl}/harvester/api/mapping/publish?fdpUrl=${this.fdpUrl}&catalogId=${catalogId}&isJsonpath=${isJsonpath}`;
 
     const myInit = { method: 'POST', body: JSON.stringify(data), headers: httpOptions};
     const myRequest = new Request(url, myInit);
diff --git a/src/app/semantic-enrichment/ConceptsRequest.ts b/src/app/semantic-enrichment/ConceptsRequest.ts
index ebb2ed93f..1e8d7c65a 100644
--- a/src/app/semantic-enrichment/ConceptsRequest.ts
+++ b/src/app/semantic-enrichment/ConceptsRequest.ts
@@ -9,4 +9,5 @@ export class ConceptsRequest {
 export class DataConcept {
   iris: string[];
   id: string;
+  url: string;
 }
diff --git a/src/app/stats/stats.component.html b/src/app/stats/stats.component.html
index 5f7379a80..2777398cf 100644
--- a/src/app/stats/stats.component.html
+++ b/src/app/stats/stats.component.html
@@ -21,7 +21,7 @@
     </thead>
     <tbody>
     <tr *ngFor="let cat of catalogList">
-      <td  style="text-align: center;">{{cat.title}}</td>
+      <td  style="text-align: center;"><a  [routerLink]="['/dashboard/edit', cat.catId]">{{cat.title}}</a></td>
       <td  style="text-align: center;"><strong>{{cat.count}}</strong></td>
     </tr>
     </tbody>
diff --git a/src/app/stats/stats.component.ts b/src/app/stats/stats.component.ts
index c72b29ad2..7e1e85be2 100644
--- a/src/app/stats/stats.component.ts
+++ b/src/app/stats/stats.component.ts
@@ -23,37 +23,36 @@ export class StatsComponent implements OnInit {
   constructor(private parserService: ParseXmlService, private catalogService: CatalogService) { }
 
   ngOnInit(): void {
+    const query1 = 'prefix dct: <http://purl.org/dc/terms/> ' +
+      'SELECT (COUNT(?s) AS ?triples) ' +
+      'WHERE { ?s a <http://www.w3.org/ns/dcat#Catalog>; ' +
+      'dct:isPartOf <' + environment.fdpUrl + '>}';
+    this.parserService.getXmlResult(query1)
+      .subscribe(data => {
+        if (data) {
+          this.results = [];
+          data.results.bindings.forEach(element => {
+            this.results.push(element);
+          });
+          this.stats.push(this.results[0]['triples'].value);
 
-      const query1 = 'prefix dct: <http://purl.org/dc/terms/> ' +
-        'SELECT (COUNT(?s) AS ?triples) ' +
-        'WHERE { ?s a <http://www.w3.org/ns/dcat#Catalog>; ' +
-        'dct:isPartOf <' + environment.fdpUrl + '>}';
-      this.parserService.getXmlResult(query1)
-        .subscribe(data => {
-          if (data) {
-            this.results = []; data.results.bindings.forEach(element => {
-              this.results.push(element);
-        });
-            this.stats.push(this.results[0]["triples"].value);
-
-            const query2 = 'prefix dct: <http://purl.org/dc/terms/> ' +
-              'SELECT (COUNT(?s) AS ?triples) ' +
-              'WHERE { ?s a <http://www.w3.org/ns/dcat#Dataset>;' +
-              ' dct:isPartOf* <' + environment.fdpUrl + '> }';
-            this.parserService.getXmlResult(query2)
-              .subscribe(data => {
-                if (data) {
-                  this.results = [];
-                  data.results.bindings.forEach(element => {
-                    this.results.push(element);
-                  });
-                  this.stats.push(this.results[0]["triples"].value); }
-              });
-
-            console.log(this.stats);
-    }
-        });
-      this.getCatalogIdByUser();
+          const query2 = 'prefix dct: <http://purl.org/dc/terms/> ' +
+            'SELECT (COUNT(?s) AS ?triples) ' +
+            'WHERE { ?s a <http://www.w3.org/ns/dcat#Dataset>;' +
+            ' dct:isPartOf* <' + environment.fdpUrl + '> }';
+          this.parserService.getXmlResult(query2)
+            .subscribe(data => {
+              if (data) {
+                this.results = [];
+                data.results.bindings.forEach(element => {
+                  this.results.push(element);
+                });
+                this.stats.push(this.results[0]['triples'].value);
+              }
+            });
+        }
+      });
+    this.getCatalogIdByUser();
     }
 
     getCatalogIdByUser() {
@@ -81,11 +80,6 @@ export class StatsComponent implements OnInit {
               )
             );
           });
-          Promise.all(titlePromises).finally(() => {
-            if (this.catalogList.length > 0) {
-              this.catalogList.sort((a, b) => a.catId.localeCompare(b.catId));
-            }
-          });
         },
         error: (error) => {
           if (error.staus === 404) { /* Ignore */ }
-- 
GitLab