From d6674600c19ec6a3d30b784fac7845fffb293029 Mon Sep 17 00:00:00 2001
From: cazenave <cazenave@cines.fr>
Date: Sun, 15 Nov 2020 15:08:32 +0100
Subject: [PATCH 01/18] add mapping

---
 package-lock.json                            |  8 +++++++
 package.json                                 |  1 +
 src/app/app.module.ts                        |  4 +++-
 src/app/mapping/mapping.component.html       |  1 +
 src/app/mapping/mapping.component.scss       |  0
 src/app/mapping/mapping.component.spec.ts    | 25 ++++++++++++++++++++
 src/app/mapping/mapping.component.ts         | 15 ++++++++++++
 src/app/publishapi/publishapi.component.html |  1 +
 8 files changed, 54 insertions(+), 1 deletion(-)
 create mode 100644 src/app/mapping/mapping.component.html
 create mode 100644 src/app/mapping/mapping.component.scss
 create mode 100644 src/app/mapping/mapping.component.spec.ts
 create mode 100644 src/app/mapping/mapping.component.ts

diff --git a/package-lock.json b/package-lock.json
index 6e2dc8224..40cb39f3d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2883,6 +2883,14 @@
         }
       }
     },
+    "@ngx-lite/json-ld": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/@ngx-lite/json-ld/-/json-ld-0.6.2.tgz",
+      "integrity": "sha512-oFWyYqBPOKQZBqP2ev3Xkn5UjjiWAC1dKYsCduvpDJTA3phc573NhPDpBqxMDfoeIuu72QOJogPehFWJV5991w==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
     "@nodelib/fs.scandir": {
       "version": "2.1.3",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
diff --git a/package.json b/package.json
index 930d39430..ff6a33d39 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
     "@angular/router": "~9.1.11",
     "@nebular/auth": "^6.2.1",
     "@nebular/theme": "^5.1.0",
+    "@ngx-lite/json-ld": "^0.6.2",
     "file-saver": "^2.0.2",
     "ng2-cookies": "^1.0.12",
     "ngx-filesaver": "^9.0.0",
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 50cab74b0..b3bb3590d 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -44,6 +44,7 @@ import { AccountComponent } from './account/account.component';
 import { AccountModule } from './account/account.module';
 import { SearchModule} from './search/search.module';
 import { StatsComponent } from './stats/stats.component';
+import { MappingComponent } from './mapping/mapping.component';
 
 
 @NgModule({
@@ -64,7 +65,8 @@ import { StatsComponent } from './stats/stats.component';
     PublishApiComponent,
     SearchComponent,
     AccountComponent,
-    StatsComponent
+    StatsComponent,
+    MappingComponent
     ],
   imports: [
     BrowserModule,
diff --git a/src/app/mapping/mapping.component.html b/src/app/mapping/mapping.component.html
new file mode 100644
index 000000000..b04ead3c3
--- /dev/null
+++ b/src/app/mapping/mapping.component.html
@@ -0,0 +1 @@
+<p>mapping works!</p>
diff --git a/src/app/mapping/mapping.component.scss b/src/app/mapping/mapping.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/app/mapping/mapping.component.spec.ts b/src/app/mapping/mapping.component.spec.ts
new file mode 100644
index 000000000..dd48d2db4
--- /dev/null
+++ b/src/app/mapping/mapping.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MappingComponent } from './mapping.component';
+
+describe('MappingComponent', () => {
+  let component: MappingComponent;
+  let fixture: ComponentFixture<MappingComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ MappingComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(MappingComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/mapping/mapping.component.ts b/src/app/mapping/mapping.component.ts
new file mode 100644
index 000000000..f5ac89394
--- /dev/null
+++ b/src/app/mapping/mapping.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-mapping',
+  templateUrl: './mapping.component.html',
+  styleUrls: ['./mapping.component.scss']
+})
+export class MappingComponent implements OnInit {
+
+  constructor() { }
+
+  ngOnInit(): void {
+  }
+
+}
diff --git a/src/app/publishapi/publishapi.component.html b/src/app/publishapi/publishapi.component.html
index 1dcac6658..fba8aa56b 100644
--- a/src/app/publishapi/publishapi.component.html
+++ b/src/app/publishapi/publishapi.component.html
@@ -36,6 +36,7 @@
           <p class="lorem">
             Map your metadata schema with DCAT schema   
           </p>
+          <app-mapping></app-mapping>
           <button class="prev-button" nbButton nbStepperPrevious>prev</button>
           <button class="next-button" nbButton nbStepperNext>next</button>
         </nb-step>
-- 
GitLab


From 1582b041ad45d9afdfc621c99b14dc2dc27a96bb Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Mon, 31 May 2021 11:34:12 +0200
Subject: [PATCH 02/18] init mapping component

---
 src/app/app.module.ts                         |  1 +
 .../authentication/services/auth.service.ts   |  2 +-
 src/app/mapping/mapping.component.html        | 23 ++++++++++++++++++-
 src/app/mapping/mapping.component.scss        | 16 +++++++++++++
 4 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 80797bb61..cb42b8198 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -63,6 +63,7 @@ import { DashboardComponent } from './dashboard/dashboard.component';
     SearchComponent,
     StatsComponent,
     DashboardComponent,
+    MappingComponent
     ],
   imports: [
     BrowserModule,
diff --git a/src/app/authentication/services/auth.service.ts b/src/app/authentication/services/auth.service.ts
index 915698895..fd53b6610 100644
--- a/src/app/authentication/services/auth.service.ts
+++ b/src/app/authentication/services/auth.service.ts
@@ -6,7 +6,7 @@ import { map } from "rxjs/operators";
 import { AppConfiguration } from 'src/app/AppConfiguration';
 
 
-const AUTH_API = "https://f2ds.eosc-pillar.eu/harvester/auth";
+const AUTH_API = "http://localhost:8080/harvester/auth";
 const F2DSAPI = "https://f2ds.eosc-pillar.eu"
 const httpOptions = {
   headers: new HttpHeaders({ 'Content-Type': 'application/json' })
diff --git a/src/app/mapping/mapping.component.html b/src/app/mapping/mapping.component.html
index b04ead3c3..a0fead3cb 100644
--- a/src/app/mapping/mapping.component.html
+++ b/src/app/mapping/mapping.component.html
@@ -1 +1,22 @@
-<p>mapping works!</p>
+<div class="card-row">
+    <div class="card-col">
+        <nb-card size="giant">
+            <nb-card-header>Dataset metadata</nb-card-header>
+            <nb-card-body></nb-card-body>
+        </nb-card>
+    </div>
+    <div class="card-col">
+        <nb-card size="giant">
+            <nb-card-header>Dcat dataset</nb-card-header>
+            <nb-card-body></nb-card-body>
+        </nb-card>
+    </div>
+</div>
+<div class="card-row">
+    <div class="card-col">
+        <nb-card>
+            <nb-card-header>Map</nb-card-header>
+            <nb-card-body></nb-card-body>
+        </nb-card>
+    </div>
+</div>
\ No newline at end of file
diff --git a/src/app/mapping/mapping.component.scss b/src/app/mapping/mapping.component.scss
index e69de29bb..b89c9d5ad 100644
--- a/src/app/mapping/mapping.component.scss
+++ b/src/app/mapping/mapping.component.scss
@@ -0,0 +1,16 @@
+:host {
+    display: block;
+    max-height: 25rem;
+    overflow-x: hidden;
+    overflow-y: auto;
+  }
+  
+  .card-row {
+    display: flex;
+    margin: 0 -0.5rem;
+  }
+  
+  .card-col {
+    flex: 1 0 calc(50% - 1rem);
+    margin: 0 0.5rem;
+  }
\ No newline at end of file
-- 
GitLab


From 352f14b81d52f70664829d5ca7b1f1c88016024f Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Mon, 31 May 2021 11:48:04 +0200
Subject: [PATCH 03/18] resolve merge conflicts

---
 src/app/authentication/services/auth.service.ts | 5 -----
 src/app/services/parse-xml.service.ts           | 4 ----
 src/environments/environment.prod.ts            | 4 ----
 3 files changed, 13 deletions(-)

diff --git a/src/app/authentication/services/auth.service.ts b/src/app/authentication/services/auth.service.ts
index a23960c77..d4ab6aa4e 100644
--- a/src/app/authentication/services/auth.service.ts
+++ b/src/app/authentication/services/auth.service.ts
@@ -6,13 +6,8 @@ import { map } from "rxjs/operators";
 import { AppConfiguration } from 'src/app/AppConfiguration';
 
 
-<<<<<<< HEAD
 const AUTH_API = "http://localhost:8080/harvester/auth";
 const F2DSAPI = "https://f2ds.eosc-pillar.eu"
-=======
-const AUTH_API = "https://ffds.eosc-pillar.eu/harvester/auth";
-const F2DSAPI = "https://ffds.eosc-pillar.eu"
->>>>>>> c3c1ead3ae1d28e003a33da588d1b6130e0145fb
 const httpOptions = {
   headers: new HttpHeaders({ 'Content-Type': 'application/json' })
 };
diff --git a/src/app/services/parse-xml.service.ts b/src/app/services/parse-xml.service.ts
index cc9d97c70..44089781b 100644
--- a/src/app/services/parse-xml.service.ts
+++ b/src/app/services/parse-xml.service.ts
@@ -7,11 +7,7 @@ import { HttpClient, HttpHeaders } from '@angular/common/http';
 })
 export class ParseXmlService {
  
-<<<<<<< HEAD
   blazePath = "https://f2ds.eosc-pillar.eu/blazegraph/sparql"
-=======
-  blazePath = "https://ffds.eosc-pillar.eu/blazegraph/sparql"
->>>>>>> c3c1ead3ae1d28e003a33da588d1b6130e0145fb
 
   constructor(private http:HttpClient) { }
   
diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts
index 44102195a..3d96a7919 100644
--- a/src/environments/environment.prod.ts
+++ b/src/environments/environment.prod.ts
@@ -1,8 +1,4 @@
 export const environment = {
   production: true,
-<<<<<<< HEAD
   apiurl: 'f2ds.eosc-pillar.eu',
-=======
-  apiurl: 'ffds.eosc-pillar.eu',
->>>>>>> c3c1ead3ae1d28e003a33da588d1b6130e0145fb
 };
-- 
GitLab


From 7aab623f89a9eefd9b6ffb703056583fe2734157 Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Fri, 25 Jun 2021 14:51:25 +0200
Subject: [PATCH 04/18] datasets descriptions

---
 src/app/app.module.ts                         |   4 +-
 src/app/datasets/datasets.component.ts        |  15 +-
 .../datasets/services/dataset-crud.service.ts |   7 +-
 src/app/mapping/mapping.component.html        |   4 +-
 src/app/mapping/mapping.component.scss        |  12 +-
 src/app/mapping/mapping.component.ts          | 167 +++++++++++++++++-
 src/app/mapping/tree/tree.component.html      |  15 ++
 src/app/mapping/tree/tree.component.scss      |   0
 src/app/mapping/tree/tree.component.spec.ts   |  25 +++
 src/app/mapping/tree/tree.component.ts        |  25 +++
 src/app/repository/repository.component.ts    |   2 +-
 src/assets/dataset.json                       | 148 ++++++++++++++++
 12 files changed, 402 insertions(+), 22 deletions(-)
 create mode 100644 src/app/mapping/tree/tree.component.html
 create mode 100644 src/app/mapping/tree/tree.component.scss
 create mode 100644 src/app/mapping/tree/tree.component.spec.ts
 create mode 100644 src/app/mapping/tree/tree.component.ts
 create mode 100644 src/assets/dataset.json

diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 56b0179d9..cfc2895ae 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -39,6 +39,7 @@ import { NbLayoutModule, NbThemeModule, NbTooltipModule, NbSpinnerModule, NbSele
 import { NbAuthModule } from '@nebular/auth/auth.module';
 import { NbDummyAuthStrategy } from '@nebular/auth/strategies/dummy/dummy-strategy';
 import { DashboardComponent } from './dashboard/dashboard.component';
+import { TreeComponent } from './mapping/tree/tree.component';
 
 
 @NgModule({
@@ -55,7 +56,8 @@ import { DashboardComponent } from './dashboard/dashboard.component';
     SearchComponent,
     StatsComponent,
     DashboardComponent,
-    MappingComponent
+    MappingComponent,
+    TreeComponent,
     ],
   imports: [
     BrowserModule,
diff --git a/src/app/datasets/datasets.component.ts b/src/app/datasets/datasets.component.ts
index f4528aafa..7b2675b5b 100644
--- a/src/app/datasets/datasets.component.ts
+++ b/src/app/datasets/datasets.component.ts
@@ -20,7 +20,7 @@ export class DatasetsComponent implements OnInit {
   Object = Object;
 
   urlrepo = "dataverse.ird.fr";
-//  urlrepo = "data.inrae.fr";
+//  urlrepo = "data.inrae.fr";  
 
   constructor(
     private appConfig: AppConfiguration,
@@ -103,7 +103,7 @@ export class DatasetsComponent implements OnInit {
 
     for (var i = 0; i < item['datasetVersion']['metadataBlocks']['citation']['fields'].length; i++) {  
      if (item['datasetVersion']['metadataBlocks']['citation']['fields'][i]['typeName'] == "dsDescription") {
-       description = JSON.stringify(item['datasetVersion']['metadataBlocks']['citation']['fields'][i]['value']);
+       description = JSON.stringify(item['datasetVersion']['metadataBlocks']['citation']['fields'][i]['value'][0]['dsDescriptionValue']['value']);
       }  
       if (item['datasetVersion']['metadataBlocks']['citation']['fields'][i]['typeName'] == "title") {
         name = JSON.stringify( item['datasetVersion']['metadataBlocks']['citation']['fields'][i]['value']  );
@@ -117,12 +117,11 @@ export class DatasetsComponent implements OnInit {
             @prefix language: <http://id.loc.gov/vocabulary/iso639-1/>.\n\
             @prefix s: <'+ this.appConfig.fdpurl + '/>.\n\
             @prefix c: <'+ this.appConfig.fdpurl + '/catalog/>.\n\
-            \n\
     s:new\n\
       a dcat:Dataset, dcat:Resource;\n\
-      dct:description '+ description + ';\n\
+      dct:description ' + description + ';\n\
       dct:hasVersion "1.0";\n\
-      dct:isPartOf c:a21f9b06-b7e7-43c0-869d-d81f09053383;\n\
+      dct:isPartOf <http://fdp-api.f2ds.svc.cluster.local/catalog/e5f49dbf-c976-4ca7-b4ee-7cc90923d9f3>;\n\
       dct:language language:en;\n\
       dct:license <http://rdflicense.appspot.com/rdflicense/cc-by-nc-nd3.0>;\n\
       dct:title '+ name + ';\n\
@@ -130,7 +129,7 @@ export class DatasetsComponent implements OnInit {
 
 
       console.log(data);
-   // return this.dataSetService.createDataSet(data);
+   //return this.dataSetService.createDataSet(data);
 
   }
 
@@ -152,8 +151,8 @@ export class DatasetsComponent implements OnInit {
   data='@prefix dcat: <http://www.w3.org/ns/dcat#>.\n\
   @prefix dct: <http://purl.org/dc/terms/>.\n\
   @prefix language: <http://id.loc.gov/vocabulary/iso639-1/>.\n\
-  @prefix ffd: <https://ffds.eosc-pillar.eu/>.\n\
-  @prefix d: <https://ffds.eosc-pillar.eu/dataset/>.\n\
+  @prefix ffd: <https://f2ds.eosc-pillar.eu/>.\n\
+  @prefix d: <https://f2ds.eosc-pillar.eu/dataset/>.\n\
   @prefix GVW: <https://dataverse.ird.fr/dataset.xhtml?persistentId=doi:10.23708/GVWCA0#>.\n\
   \n\
   ffd:new\n\
diff --git a/src/app/datasets/services/dataset-crud.service.ts b/src/app/datasets/services/dataset-crud.service.ts
index 3abb6be9e..a1b0657ab 100644
--- a/src/app/datasets/services/dataset-crud.service.ts
+++ b/src/app/datasets/services/dataset-crud.service.ts
@@ -1,5 +1,6 @@
 import { HttpClient, HttpHeaders } from '@angular/common/http';
 import { Injectable } from '@angular/core';
+import { Observable } from 'rxjs';
 import { AppConfiguration } from 'src/app/AppConfiguration';
 import { AuthService } from 'src/app/authentication/services/auth.service';
 import { ParseXmlService } from '../../services/parse-xml.service';
@@ -28,7 +29,7 @@ export class DatasetCrudService {
         })
       };
       
-      let resultat = this.http.post(this.appConfig.fdpurl+"/catalog", data, httpOptions ).subscribe( (r)=>{console.log('reponse: ', r)}) ;
+      let resultat = this.http.post(this.appConfig.fdpurl+"/dataset", data, httpOptions ).subscribe( (r)=>{console.log('reponse: ', r)}) ;
       if (resultat){
         console.log("resultat: " + JSON.stringify(resultat));
         return JSON.stringify(resultat);
@@ -78,6 +79,10 @@ export class DatasetCrudService {
       return exist
   }
 
+  getLocally<T = any>(path: string): Observable<T> {
+    console.log('On getLocally using filepath : ', `${path}`);
+    return this.http.get<T>(`${path}`);
+  }
 
 
 }
diff --git a/src/app/mapping/mapping.component.html b/src/app/mapping/mapping.component.html
index a0fead3cb..003393480 100644
--- a/src/app/mapping/mapping.component.html
+++ b/src/app/mapping/mapping.component.html
@@ -2,7 +2,9 @@
     <div class="card-col">
         <nb-card size="giant">
             <nb-card-header>Dataset metadata</nb-card-header>
-            <nb-card-body></nb-card-body>
+            <nb-card-body>
+                <app-tree [items]="Object.keys(itemsdataset)" [itemsDataset]="itemsdataset"></app-tree>
+            </nb-card-body>
         </nb-card>
     </div>
     <div class="card-col">
diff --git a/src/app/mapping/mapping.component.scss b/src/app/mapping/mapping.component.scss
index b89c9d5ad..2326b68a6 100644
--- a/src/app/mapping/mapping.component.scss
+++ b/src/app/mapping/mapping.component.scss
@@ -1,16 +1,12 @@
-:host {
-    display: block;
-    max-height: 25rem;
-    overflow-x: hidden;
-    overflow-y: auto;
-  }
-  
+
   .card-row {
     display: flex;
+    flex: 1 0 calc(100%);
     margin: 0 -0.5rem;
   }
   
   .card-col {
-    flex: 1 0 calc(50% - 1rem);
+    width: 50%;
+    flex: calc(50% );
     margin: 0 0.5rem;
   }
\ No newline at end of file
diff --git a/src/app/mapping/mapping.component.ts b/src/app/mapping/mapping.component.ts
index f5ac89394..75a75adbf 100644
--- a/src/app/mapping/mapping.component.ts
+++ b/src/app/mapping/mapping.component.ts
@@ -1,4 +1,10 @@
+import { HttpClient } from '@angular/common/http';
 import { Component, OnInit } from '@angular/core';
+import { FormControl, FormGroup } from '@angular/forms';
+import { FileSaverService } from 'ngx-filesaver';
+import { AppConfiguration } from '../AppConfiguration';
+import { DatasetCrudService } from '../datasets/services/dataset-crud.service';
+
 
 @Component({
   selector: 'app-mapping',
@@ -7,9 +13,166 @@ import { Component, OnInit } from '@angular/core';
 })
 export class MappingComponent implements OnInit {
 
-  constructor() { }
+  itemsdatasets: any;
+  itemsdataset: Object;
+  fields : Map<number, string[]>;
+  Object = Object;
+
+  urlrepo = "dataverse.ird.fr";
+  //  urlrepo = "data.inrae.fr";
+
+  constructor(
+    private appConfig: AppConfiguration,
+    private dataSetService: DatasetCrudService
+  ) { }
+
+  ngOnInit() {
+    this.itemsdataset = [];
+    this.listdatasets();
+    
+
+  }
+
+  listdatasets() {
+    var myHeaders = new Headers();
+    myHeaders.append("Content-Type", "Application/json");
+    var myInit = { method: 'GET', headers: myHeaders };
+
+
+    //appeler smart havester pour récuperer l'api à lancer
+
+
+    var myRequest = new Request('https://' + this.urlrepo + '/api/search?q=*&per_page=5&type=dataset&start=50&show_facets=true&show_my_data=true', myInit);
 
-  ngOnInit(): void {
+    fetch(myRequest, myInit)
+      .then(response => {
+        response.json()
+          .then(data => {
+            this.itemsdatasets = data['data']['items'];
+      
+            for (var i = 0; i < this.itemsdatasets.length; i++) {
+              if (!this.dataSetService.findDataSetByTitle(this.itemsdatasets[i]['name'])) {
+                if (data['data']['items'][i]['global_id']) {
+                  this.populatecatalogue(data['data']['items'][i]['global_id']);
+                }
+              }
+            }
+          });
+      });
+    return null;
   }
 
+
+  populatecatalogue(id: string) {
+    var myHeaders = new Headers();
+    myHeaders.append("Content-Type", "Application/json");
+    var myInit = { method: 'GET', headers: myHeaders };
+
+    //appeler smart havester pour récuperer l'api à lancer
+
+    var myRequest = new Request('https://' + this.urlrepo + '/api/datasets/export?exporter=dataverse_json&persistentId=' + id, myInit);
+
+    fetch(myRequest, myInit)
+      .then(response => {
+        response.json()
+          .then(data => {
+            this.itemsdataset = data;
+            //this.createdataset(this.itemsdataset);
+            //this.createdistribution(this.itemsdataset);                       
+          });
+      });
+
+
+
+
+  }
+
+
+
+
+  createdataset(item: any) {
+    //console.log(item);
+    let data: string;
+    let description = "";
+    let name = "";
+    let url: string;
+
+    for (var i = 0; i < item['datasetVersion']['metadataBlocks']['citation']['fields'].length; i++) {
+      if (item['datasetVersion']['metadataBlocks']['citation']['fields'][i]['typeName'] == "dsDescription") {
+        description = JSON.stringify(item['datasetVersion']['metadataBlocks']['citation']['fields'][i]['value']);
+      }
+      if (item['datasetVersion']['metadataBlocks']['citation']['fields'][i]['typeName'] == "title") {
+        name = JSON.stringify(item['datasetVersion']['metadataBlocks']['citation']['fields'][i]['value']);
+      }
+    }
+
+    url = JSON.stringify(item['persistentUrl']);
+
+    data = '\@prefix dcat: <http://www.w3.org/ns/dcat#>.\n\
+            @prefix dct: <http://purl.org/dc/terms/>.\n\
+            @prefix language: <http://id.loc.gov/vocabulary/iso639-1/>.\n\
+            @prefix s: <'+ this.appConfig.fdpurl + '/>.\n\
+            @prefix c: <'+ this.appConfig.fdpurl + '/catalog/>.\n\
+            \n\
+    s:new\n\
+      a dcat:Dataset, dcat:Resource;\n\
+      dct:description '+ description + ';\n\
+      dct:hasVersion "1.0";\n\
+      dct:isPartOf c:e5f49dbf-c976-4ca7-b4ee-7cc90923d9f3;\n\
+      dct:language language:en;\n\
+      dct:license <http://rdflicense.appspot.com/rdflicense/cc-by-nc-nd3.0>;\n\
+      dct:title '+ name + ';\n\
+      dcat:keyword '+ url + '.\n'
+
+
+    console.log('data: ' + data);
+    return this.dataSetService.createDataSet(data);
+
+  }
+
+
+
+  createdistribution(item: any) {
+
+    // si file alors download url https://dataverse.ird.fr/api/access/datafile/['files']['dataFile'][i]['id']]
+
+    console.log(item);
+    let data: string;
+    let description: string;
+    description = JSON.stringify(item['description']);
+    let name: string;
+    name = JSON.stringify(item['name']);
+    let url: string;
+    url = JSON.stringify(item['url']);
+
+    data = '@prefix dcat: <http://www.w3.org/ns/dcat#>.\n\
+  @prefix dct: <http://purl.org/dc/terms/>.\n\
+  @prefix language: <http://id.loc.gov/vocabulary/iso639-1/>.\n\
+  @prefix ffd: <https://f2ds.eosc-pillar.eu/>.\n\
+  @prefix d: <https://f2ds.eosc-pillar.eu/dataset/>.\n\
+  @prefix GVW: <https://dataverse.ird.fr/dataset.xhtml?persistentId=doi:10.23708/GVWCA0#>.\n\
+  \n\
+  ffd:new\n\
+      a dcat:Distribution, dcat:Resource;\n\
+      dct:description "Botinelli_VNM_2016.png ";\n\
+      dct:hasVersion "v1.0";\n\
+      dct:isPartOf d:e5f49dbf-c976-4ca7-b4ee-7cc90923d9f3;\n\
+      dct:language language:fr;\n\
+      dct:license <http://rdflicense.appspot.com/rdflicense/cc-by-nc-nd3.0>;\n\
+      dct:title "Botinelli_VNM_2016.png ";\n\
+      dcat:accessURL GVW:;\n\
+      dcat:downloadURL\n\
+      <https://dataverse.ird.fr/api/access/datafile/262?imageThumb=400>;\n\
+      dcat:format "png";\n\
+      dcat:mediaType "png".'
+
+
+    return this.dataSetService.createDistribution(data);
+  }
+
+ 
+
+ 
+
+  
 }
diff --git a/src/app/mapping/tree/tree.component.html b/src/app/mapping/tree/tree.component.html
new file mode 100644
index 000000000..78b0caf8e
--- /dev/null
+++ b/src/app/mapping/tree/tree.component.html
@@ -0,0 +1,15 @@
+
+    <div *ngFor="let item of items">
+        <ul>
+            <li>
+                <label>
+                    {{item}}
+                </label>
+                <input *ngIf="!isObject(itemsDataset[item])"  type="text" value="{{itemsDataset[item]}}" disabled >
+            </li>
+        </ul>
+        <ul *ngIf="isObject(itemsDataset[item])">
+            <app-tree [items]="Object.keys(itemsDataset[item])" [itemsDataset]="itemsDataset[item]"></app-tree> 
+        </ul>
+
+    </div>
diff --git a/src/app/mapping/tree/tree.component.scss b/src/app/mapping/tree/tree.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/app/mapping/tree/tree.component.spec.ts b/src/app/mapping/tree/tree.component.spec.ts
new file mode 100644
index 000000000..e3df2c328
--- /dev/null
+++ b/src/app/mapping/tree/tree.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TreeComponent } from './tree.component';
+
+describe('TreeComponent', () => {
+  let component: TreeComponent;
+  let fixture: ComponentFixture<TreeComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ TreeComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(TreeComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/mapping/tree/tree.component.ts b/src/app/mapping/tree/tree.component.ts
new file mode 100644
index 000000000..e33d93f4f
--- /dev/null
+++ b/src/app/mapping/tree/tree.component.ts
@@ -0,0 +1,25 @@
+import { Component, Input, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-tree',
+  templateUrl: './tree.component.html',
+  styleUrls: ['./tree.component.scss']
+})
+export class TreeComponent implements OnInit {
+  @Input() items;
+  @Input() itemsDataset;
+  Object = Object;
+
+  constructor() { }
+
+  ngOnInit(): void {
+  }
+
+  isObject(object: Object): boolean{
+    if(typeof object === 'object'){
+      return true;
+    } else {
+      return false;
+    }
+  }
+}
diff --git a/src/app/repository/repository.component.ts b/src/app/repository/repository.component.ts
index bb17611ec..5ef513406 100644
--- a/src/app/repository/repository.component.ts
+++ b/src/app/repository/repository.component.ts
@@ -110,7 +110,7 @@ repository:\n\
     a dcat:Catalog, dcat:Resource;\n\
     dct:description "'+ this.Form.value.repodescription + '";\n\
     dct:hasVersion "'+ this.Form.value.repoversion + '";\n\
-    dct:isPartOf <'+ this.appConfig.fdpurl + '>;\n\
+    dct:isPartOf <http://146.59.2.80>;\n\
     dcat:keyword "'+ this.Form.value.repotype + '";\n\
     dct:title "'+ this.Form.value.reponame + '".\n'
 
diff --git a/src/assets/dataset.json b/src/assets/dataset.json
new file mode 100644
index 000000000..14e72c039
--- /dev/null
+++ b/src/assets/dataset.json
@@ -0,0 +1,148 @@
+{
+  "description": {
+    "identier": "dct:descritpion",
+    "usageNote": "Mandatory property. This property contains a free-text account of the Dataset. This property can be repeated for parallel language versions of the description."
+  },
+  "title": {
+    "identifier": "dct:title",
+    "usageNote": "Mandatory property. This property contains a name given to the Dataset. This property can be repeated for parallel language versions of the name."
+  },
+  "contactPoint": {
+    "identifier": "dcat:contactPoint",
+    "usageNote": "Recommended property.This property contains contact information that can be used for sending comments about the Dataset."
+  },
+  "distribution": {
+    "identifier": "dcat:distribution",
+    "usageNote": "Recommended property. This property links the Dataset to an available Distribution."
+  },
+  "keyword": {
+    "identifier": "dcat:keyword",
+    "usageNote": "Recommended property. This property contains a keyword or tag describing the Dataset."
+  },
+  "publisher": {
+    "identifier": "dct:publisher",
+    "usageNote": "Recommended property. This property refers to an entity (organisation) responsible for making the Dataset available."
+  },
+  "spatial": {
+    "identifier": "dct:spatial",
+    "usageNote": "Recommended property. This property refers to a geographic region that is covered by the Dataset. "
+  },
+  "theme": {
+    "identifier": "dcat:theme",
+    "usageNote": "Recommended property. This property refers to a category of the Dataset. A Dataset may be associated with multiple themes. Subproperty of dct:subject."
+  },
+  "temporal": {
+    "identifier": "dct:temporal",
+    "usageNote": "Recommended property. This property refers to a temporal period that the Dataset covers."
+  },
+  "conformsTo": {
+    "identifier": "dct:conformsTo",
+    "usageNote": "Optional property. This property refers to an implementing rule or other specification."
+  },
+  "accrualPeriodicity": {
+    "identifier": "dct:accrualPeriodicity",
+    "usageNote": "Optional property. This property refers to the frequency at which Dataset is updated."
+  },
+  "identifier": {
+    "identifier": "dct:identifier",
+    "usageNote": "Optional property. This property contains the main identifier for the Dataset, e.g. the URI or other unique identifier in the context of the Catalogue."
+  },
+  "landingPage": {
+    "identifier": "dcat:landingPage",
+    "usageNote": "Optional property. This property refers to a web page that provides access to the Dataset, its Distributions and/or additional information."
+  },
+  "language": {
+    "identifier": "dct:language",
+    "usageNote": "Optional property. This property refers to a language of the Dataset. This property can be repeated if there are multiple languages in the Dataset."
+  },
+  "other identifier": {
+    "identifier": "adms:identifier",
+    "usageNote": "Optional property. This property contains the date of formal issuance (e.g., publication) of the Dataset."
+  },
+  "issued": {
+    "identifier": "dct:issued",
+    "usageNote": "Optional property. This property contains the date of formal issuance (e.g., publication) of the Dataset."
+  },
+  "modified": {
+    "identifier": "dct:modified",
+    "usageNote": "Optional property. This property contains the most recent date on which the Dataset was changed or modified."
+  },
+  "provenance": {
+    "identifier": "dct:provenance",
+    "usageNote": "Optional property. This property contains a statement about the lineage of a Dataset."
+  },
+  "sample": {
+    "identifier": "adms:sample",
+    "usageNote": "Optional property. This property refers to a sample distribution of the dataset."
+  },
+  "source": {
+    "identifier": "dct:source",
+    "usageNote": "Optional property. This property refers to a related Dataset from which the described Dataset is derived."
+  },
+  "type": {
+    "identifier": "dct:type",
+    "usageNote": "Optional property. This property refers to the type of the Dataset. A controlled vocabulary for the values has not been established."
+  },
+  "relation": {
+    "identifier": "dct:relation",
+    "usageNote": "Optional property. This property refers to a related resource."
+  },
+  "versionInfo": {
+    "identifier": "owl:versionInfo",
+    "usageNote": "Optional property. This property contains a version number or other version designation of the Dataset."
+  },
+  "versionNotes": {
+    "identifier": "adms:versionNotes",
+    "usageNote": "Optional property. This property contains a description of the differences between this version and a previous version of the Dataset."
+  },
+  "isVersionOf": {
+    "identifier": "dct:isVersionOf",
+    "usageNote": "Optional property. This property refers to a related Dataset of which the described Dataset is a version, edition, or adaptation."
+  },
+  "hasVersion": {
+    "identifier": "dct:hasVersion",
+    "usageNote": "Optional property.This property refers to a related Dataset that is a version, edition, or adaptation of the described Dataset."
+  },
+  "page": {
+    "identifier": "foaf:page",
+    "usageNote": "Optional property. This property refers to a page or document about this Dataset."
+  },
+  "accessRights": {
+    "identifier": "dct:accessRights",
+    "usageNote": "Optional property. This property refers to information that indicates whether the Dataset is open data, has access restrictions or is not public. A controlled vocabulary with three members (:public, :restricted, :non-public) will be created and maintained by the Publications Office of the EU."
+  },
+  "creator": {
+    "identifier": "dct:creator",
+    "usageNote": "Optional property. This property refers to an entity primarily responsible for making the resource."
+  },
+  "qualifiedAttribution": {
+    "identifier": "prov:qualifiedAttribution",
+    "usageNote": "Optional property. This property refers to the link to an Agent having some form of responsibility for the resource. "
+  },
+  "wasGeneratedBy": {
+    "identifier": "prov:wasGeneratedBy",
+    "usageNote": "Optional property. This property refers to an activity that generated, or provides the business context for, the creation of the dataset."
+  },
+  "temporalResolution": {
+    "identifier": "dcat:temporalResolution",
+    "usageNote": "This property refers to the minimum time period resolvable in the dataset."
+  },
+  "spatialResolutionInMeters": {
+    "identifier": "dcat:spatialResolutionInMeters",
+    "usageNote": "Optional property. This property refers to the minimum spatial separation resolvable in a dataset, measured in meters. "
+  },
+  "qualifiedRelation": {
+    "identifier": "dcat:qualifiedRelation",
+    "usageNote": "Optional property. This property provides a link to a description of a relationship with another resource."
+  },
+  "isReferencedBy": {
+    "identifier": "dct:isReferencedBy",
+    "usageNote": "Optional property. This property refers to a related resource, such as a publication, that references, cites, or otherwise points to the dataset."
+  }
+
+  
+
+
+
+
+}
\ No newline at end of file
-- 
GitLab


From 400da95da016942ddd764dedc744388d9b38fa4c Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Mon, 28 Jun 2021 15:34:30 +0200
Subject: [PATCH 05/18] parmeters from dcat

---
 package.json                                  |   2 +-
 src/app/app-routing.module.ts                 |   1 -
 src/app/app.module.ts                         |   3 +-
 .../datasets/services/dataset-crud.service.ts |   8 +-
 src/app/mapping/class/dataset.ts              |   6 +
 src/app/mapping/mapping.component.html        |   9 +-
 src/app/mapping/mapping.component.scss        |  11 ++
 src/app/mapping/mapping.component.ts          |  84 +++++--------
 src/app/mapping/tree/tree.component.html      |  36 ++++--
 src/app/mapping/tree/tree.component.scss      |  19 +++
 src/app/mapping/tree/tree.component.ts        |  11 +-
 src/assets/dataset.json                       | 117 +++++++++++-------
 12 files changed, 186 insertions(+), 121 deletions(-)
 create mode 100644 src/app/mapping/class/dataset.ts

diff --git a/package.json b/package.json
index 68906ca9c..3a089dcb9 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
   "scripts": {
     "ng": "ng",
     "start": "ng serve",
-    "build": "ng build",
+    "build": "ng build ",
     "test": "ng test",
     "lint": "ng lint",
     "e2e": "ng e2e"
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 8ffa36222..7dba399fd 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -12,7 +12,6 @@ import { SearchComponent } from './search/search.component';
 import { AuthenticationComponent } from './authentication/authentication.component';
 import { SigninComponent } from './authentication/signin/signin.component';
 import { SignupComponent } from './authentication/signup/signup.component';
-import { AppComponent } from './app.component';
 import { DashboardComponent } from './dashboard/dashboard.component';
 import { AuthGuardService } from './authentication/services/auth.guard';
 import { StatsComponent } from './stats/stats.component';
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index cfc2895ae..39fc439ff 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -42,6 +42,7 @@ import { DashboardComponent } from './dashboard/dashboard.component';
 import { TreeComponent } from './mapping/tree/tree.component';
 
 
+
 @NgModule({
   declarations: [
     AppComponent,
@@ -82,7 +83,7 @@ import { TreeComponent } from './mapping/tree/tree.component';
     NbSpinnerModule,
     NbSelectModule,
     NbTabsetModule,
-    NbTooltipModule
+    NbTooltipModule,
   ],
 
   providers: [
diff --git a/src/app/datasets/services/dataset-crud.service.ts b/src/app/datasets/services/dataset-crud.service.ts
index a1b0657ab..d981d8cb0 100644
--- a/src/app/datasets/services/dataset-crud.service.ts
+++ b/src/app/datasets/services/dataset-crud.service.ts
@@ -60,7 +60,11 @@ export class DatasetCrudService {
     }
   }
 
-
+  getDatasetsFromApi(url: string, params: string): Observable<any[]> {
+    const httpOptions = {
+      headers: new HttpHeaders({'Content-Type':  'Application/json'})};
+    return this.http.get<any[]>(`${url}/${params}`, httpOptions);
+  }
 
   findDataSetByTitle(title:string){
 
@@ -72,7 +76,7 @@ export class DatasetCrudService {
         this.results = []; 
         data.results.bindings.forEach(element => { this.results.push(element);});
          if (this.results[0]) {
-          console.log(this.results[0]['uri'].value.substring(36,72));
+          
           let exist = true;
          }
         }});
diff --git a/src/app/mapping/class/dataset.ts b/src/app/mapping/class/dataset.ts
new file mode 100644
index 000000000..ed57278a8
--- /dev/null
+++ b/src/app/mapping/class/dataset.ts
@@ -0,0 +1,6 @@
+export class Dataset {
+    public name: string;
+    public identifier: string;
+    public usageNote: string;
+}
+
diff --git a/src/app/mapping/mapping.component.html b/src/app/mapping/mapping.component.html
index 003393480..7e279ea49 100644
--- a/src/app/mapping/mapping.component.html
+++ b/src/app/mapping/mapping.component.html
@@ -3,16 +3,11 @@
         <nb-card size="giant">
             <nb-card-header>Dataset metadata</nb-card-header>
             <nb-card-body>
-                <app-tree [items]="Object.keys(itemsdataset)" [itemsDataset]="itemsdataset"></app-tree>
+                <app-tree  [itemsDataset]="itemsdataset" [datasetModel]="datasetModel"></app-tree>
             </nb-card-body>
         </nb-card>
     </div>
-    <div class="card-col">
-        <nb-card size="giant">
-            <nb-card-header>Dcat dataset</nb-card-header>
-            <nb-card-body></nb-card-body>
-        </nb-card>
-    </div>
+    
 </div>
 <div class="card-row">
     <div class="card-col">
diff --git a/src/app/mapping/mapping.component.scss b/src/app/mapping/mapping.component.scss
index 2326b68a6..d7a337d69 100644
--- a/src/app/mapping/mapping.component.scss
+++ b/src/app/mapping/mapping.component.scss
@@ -4,8 +4,19 @@
     flex: 1 0 calc(100%);
     margin: 0 -0.5rem;
   }
+  .row {
+    display: flex;
+    flex: 1 0 calc(100%);
+    margin: 0 -0.5rem;
+  }
   
   .card-col {
+    width: 100%;
+    flex: calc(50% );
+    margin: 0 0.5rem;
+  }
+
+  .col-6 {
     width: 50%;
     flex: calc(50% );
     margin: 0 0.5rem;
diff --git a/src/app/mapping/mapping.component.ts b/src/app/mapping/mapping.component.ts
index 75a75adbf..2d65fc058 100644
--- a/src/app/mapping/mapping.component.ts
+++ b/src/app/mapping/mapping.component.ts
@@ -1,9 +1,10 @@
-import { HttpClient } from '@angular/common/http';
+
 import { Component, OnInit } from '@angular/core';
-import { FormControl, FormGroup } from '@angular/forms';
-import { FileSaverService } from 'ngx-filesaver';
+import { Observable } from 'rxjs';
 import { AppConfiguration } from '../AppConfiguration';
 import { DatasetCrudService } from '../datasets/services/dataset-crud.service';
+import { Dataset } from './class/Dataset';
+
 
 
 @Component({
@@ -15,76 +16,57 @@ export class MappingComponent implements OnInit {
 
   itemsdatasets: any;
   itemsdataset: Object;
-  fields : Map<number, string[]>;
+  datasetModel: Dataset[];
   Object = Object;
 
-  urlrepo = "dataverse.ird.fr";
+  urlrepo = "https://dataverse.ird.fr";
   //  urlrepo = "data.inrae.fr";
 
   constructor(
     private appConfig: AppConfiguration,
     private dataSetService: DatasetCrudService
-  ) { }
+  ) {
+      
+    }
 
   ngOnInit() {
     this.itemsdataset = [];
     this.listdatasets();
+    this.dataSetService.getLocally('./assets/dataset.json').subscribe(
+      dataset => this.datasetModel = dataset,
+      error => console.error(error)
+    );
+    
     
-
   }
+  
 
   listdatasets() {
-    var myHeaders = new Headers();
-    myHeaders.append("Content-Type", "Application/json");
-    var myInit = { method: 'GET', headers: myHeaders };
-
-
     //appeler smart havester pour récuperer l'api à lancer
-
-
-    var myRequest = new Request('https://' + this.urlrepo + '/api/search?q=*&per_page=5&type=dataset&start=50&show_facets=true&show_my_data=true', myInit);
-
-    fetch(myRequest, myInit)
-      .then(response => {
-        response.json()
-          .then(data => {
-            this.itemsdatasets = data['data']['items'];
+    let params = 'api/search?q=*&per_page=5&type=dataset&start=50&show_facets=true&show_my_data=true';
+    this.dataSetService.getDatasetsFromApi(this.urlrepo, params).subscribe(data => {
+      this.itemsdatasets = data['data']['items'];
       
-            for (var i = 0; i < this.itemsdatasets.length; i++) {
-              if (!this.dataSetService.findDataSetByTitle(this.itemsdatasets[i]['name'])) {
-                if (data['data']['items'][i]['global_id']) {
-                  this.populatecatalogue(data['data']['items'][i]['global_id']);
-                }
-              }
-            }
-          });
-      });
-    return null;
+      for (var i = 0; i < this.itemsdatasets.length; i++) {
+        if (!this.dataSetService.findDataSetByTitle(this.itemsdatasets[i]['name'])) {
+          if (data['data']['items'][i]['global_id']) {
+            this.populatecatalogue(data['data']['items'][i]['global_id']);
+          }
+        }
+      }
+    });
   }
 
 
   populatecatalogue(id: string) {
-    var myHeaders = new Headers();
-    myHeaders.append("Content-Type", "Application/json");
-    var myInit = { method: 'GET', headers: myHeaders };
-
+    let params = `api/datasets/export?exporter=dataverse_json&persistentId=${id}`;
+    
     //appeler smart havester pour récuperer l'api à lancer
-
-    var myRequest = new Request('https://' + this.urlrepo + '/api/datasets/export?exporter=dataverse_json&persistentId=' + id, myInit);
-
-    fetch(myRequest, myInit)
-      .then(response => {
-        response.json()
-          .then(data => {
-            this.itemsdataset = data;
-            //this.createdataset(this.itemsdataset);
-            //this.createdistribution(this.itemsdataset);                       
-          });
-      });
-
-
-
-
+    this.dataSetService.getDatasetsFromApi(this.urlrepo, params).subscribe(data => {
+      this.itemsdataset = data;
+      //this.createdataset(this.itemsdataset);
+      //this.createdistribution(this.itemsdataset); 
+    });
   }
 
 
diff --git a/src/app/mapping/tree/tree.component.html b/src/app/mapping/tree/tree.component.html
index 78b0caf8e..bd2c7ad11 100644
--- a/src/app/mapping/tree/tree.component.html
+++ b/src/app/mapping/tree/tree.component.html
@@ -1,15 +1,27 @@
 
-    <div *ngFor="let item of items">
-        <ul>
-            <li>
-                <label>
-                    {{item}}
-                </label>
-                <input *ngIf="!isObject(itemsDataset[item])"  type="text" value="{{itemsDataset[item]}}" disabled >
-            </li>
-        </ul>
-        <ul *ngIf="isObject(itemsDataset[item])">
-            <app-tree [items]="Object.keys(itemsDataset[item])" [itemsDataset]="itemsDataset[item]"></app-tree> 
-        </ul>
+<div *ngFor="let item of Object.keys(itemsDataset); let i ">
 
+    <div class="row">
+        
+        <dl>
+            <dt>
+                <h5>
+                    {{item}}
+                </h5>
+                <input *ngIf="!isObject(itemsDataset[item])" type="text" value="{{itemsDataset[item]}}" disabled>
+                <nb-select [size]="size" *ngIf="!isObject(itemsDataset[item])" >
+                        <nb-option value="">no value</nb-option>
+                        <nb-option *ngFor="let data of datasetModel " value="{{ data.identifier}}">{{ data.name}} ({{ data.identifier}})</nb-option>
+                    
+                </nb-select>
+            </dt>
+            
+        </dl>
     </div>
+
+
+    <dl *ngIf="isObject(itemsDataset[item])">
+        <app-tree  [itemsDataset]="itemsDataset[item]" ></app-tree>
+    </dl>
+
+</div>
\ No newline at end of file
diff --git a/src/app/mapping/tree/tree.component.scss b/src/app/mapping/tree/tree.component.scss
index e69de29bb..72f397eed 100644
--- a/src/app/mapping/tree/tree.component.scss
+++ b/src/app/mapping/tree/tree.component.scss
@@ -0,0 +1,19 @@
+dl, dt, dd {
+    margin-left: 10px;
+}
+
+.row {
+    display: block;
+}
+
+input {
+    float: left;
+    width: 60%;
+    padding: 10px;
+}
+
+select {
+    float: left;
+    width: 40%;
+    padding: 10px;
+}
\ No newline at end of file
diff --git a/src/app/mapping/tree/tree.component.ts b/src/app/mapping/tree/tree.component.ts
index e33d93f4f..6278c0144 100644
--- a/src/app/mapping/tree/tree.component.ts
+++ b/src/app/mapping/tree/tree.component.ts
@@ -1,4 +1,7 @@
 import { Component, Input, OnInit } from '@angular/core';
+import { NbComponentSize } from '@nebular/theme';
+import { Observable } from 'rxjs';
+import { Dataset } from '../class/Dataset';
 
 @Component({
   selector: 'app-tree',
@@ -6,11 +9,15 @@ import { Component, Input, OnInit } from '@angular/core';
   styleUrls: ['./tree.component.scss']
 })
 export class TreeComponent implements OnInit {
-  @Input() items;
+  
   @Input() itemsDataset;
+  @Input() datasetModel: Dataset[];
   Object = Object;
+  size: NbComponentSize =  'medium';
 
-  constructor() { }
+  constructor() { 
+
+  }
 
   ngOnInit(): void {
   }
diff --git a/src/assets/dataset.json b/src/assets/dataset.json
index 14e72c039..9e96bc255 100644
--- a/src/assets/dataset.json
+++ b/src/assets/dataset.json
@@ -1,148 +1,177 @@
-{
-  "description": {
-    "identier": "dct:descritpion",
+[
+  {
+    "name": "descritpion",
+    "identifier": "dct:descritpion",
     "usageNote": "Mandatory property. This property contains a free-text account of the Dataset. This property can be repeated for parallel language versions of the description."
   },
-  "title": {
+  {
+    "name": "title",
     "identifier": "dct:title",
     "usageNote": "Mandatory property. This property contains a name given to the Dataset. This property can be repeated for parallel language versions of the name."
   },
-  "contactPoint": {
+  {
+    "name": "contact point",
     "identifier": "dcat:contactPoint",
     "usageNote": "Recommended property.This property contains contact information that can be used for sending comments about the Dataset."
   },
-  "distribution": {
+  {
+    "name": "dataset distribution",
     "identifier": "dcat:distribution",
     "usageNote": "Recommended property. This property links the Dataset to an available Distribution."
   },
-  "keyword": {
+  {
+    "name": "keyword/ tag",
     "identifier": "dcat:keyword",
     "usageNote": "Recommended property. This property contains a keyword or tag describing the Dataset."
   },
-  "publisher": {
+  {
+    "name": "publisher",
     "identifier": "dct:publisher",
     "usageNote": "Recommended property. This property refers to an entity (organisation) responsible for making the Dataset available."
   },
-  "spatial": {
+  {
+    "name": "spatial/geographical coverage",
     "identifier": "dct:spatial",
     "usageNote": "Recommended property. This property refers to a geographic region that is covered by the Dataset. "
   },
-  "theme": {
+  {
+    "name": "theme/category",
     "identifier": "dcat:theme",
     "usageNote": "Recommended property. This property refers to a category of the Dataset. A Dataset may be associated with multiple themes. Subproperty of dct:subject."
   },
-  "temporal": {
+  {
+    "name": "temporal coverage",
     "identifier": "dct:temporal",
     "usageNote": "Recommended property. This property refers to a temporal period that the Dataset covers."
   },
-  "conformsTo": {
+  {
+    "name": "conforms to",
     "identifier": "dct:conformsTo",
     "usageNote": "Optional property. This property refers to an implementing rule or other specification."
   },
-  "accrualPeriodicity": {
+  {
+    "name": "frequency",
     "identifier": "dct:accrualPeriodicity",
     "usageNote": "Optional property. This property refers to the frequency at which Dataset is updated."
   },
-  "identifier": {
+  {
+    "name": "identifier",
     "identifier": "dct:identifier",
     "usageNote": "Optional property. This property contains the main identifier for the Dataset, e.g. the URI or other unique identifier in the context of the Catalogue."
   },
-  "landingPage": {
+  {
+    "name": "landing page",
     "identifier": "dcat:landingPage",
     "usageNote": "Optional property. This property refers to a web page that provides access to the Dataset, its Distributions and/or additional information."
   },
-  "language": {
+  {
+    "name": "language",
     "identifier": "dct:language",
     "usageNote": "Optional property. This property refers to a language of the Dataset. This property can be repeated if there are multiple languages in the Dataset."
   },
-  "other identifier": {
+  {
+    "name": "other identifier",
     "identifier": "adms:identifier",
     "usageNote": "Optional property. This property contains the date of formal issuance (e.g., publication) of the Dataset."
   },
-  "issued": {
+  {
+    "name": "release date datele",
     "identifier": "dct:issued",
     "usageNote": "Optional property. This property contains the date of formal issuance (e.g., publication) of the Dataset."
   },
-  "modified": {
+  {
+    "name": "update/modification date",
     "identifier": "dct:modified",
     "usageNote": "Optional property. This property contains the most recent date on which the Dataset was changed or modified."
   },
-  "provenance": {
+  {
+    "name": "provenance",
     "identifier": "dct:provenance",
     "usageNote": "Optional property. This property contains a statement about the lineage of a Dataset."
   },
-  "sample": {
+  {
+    "name": "sample",
     "identifier": "adms:sample",
     "usageNote": "Optional property. This property refers to a sample distribution of the dataset."
   },
-  "source": {
+  {
+    "name": "source",
     "identifier": "dct:source",
     "usageNote": "Optional property. This property refers to a related Dataset from which the described Dataset is derived."
   },
-  "type": {
+  {
+    "name": "type",
     "identifier": "dct:type",
     "usageNote": "Optional property. This property refers to the type of the Dataset. A controlled vocabulary for the values has not been established."
   },
-  "relation": {
+  {
+    "name": "related resource",
     "identifier": "dct:relation",
     "usageNote": "Optional property. This property refers to a related resource."
   },
-  "versionInfo": {
+  {
+    "name": "version",
     "identifier": "owl:versionInfo",
     "usageNote": "Optional property. This property contains a version number or other version designation of the Dataset."
   },
-  "versionNotes": {
+  {
+    "name": "version notes",
     "identifier": "adms:versionNotes",
     "usageNote": "Optional property. This property contains a description of the differences between this version and a previous version of the Dataset."
   },
-  "isVersionOf": {
+  {
+    "name": "is Version Of",
     "identifier": "dct:isVersionOf",
     "usageNote": "Optional property. This property refers to a related Dataset of which the described Dataset is a version, edition, or adaptation."
   },
-  "hasVersion": {
+  {
+    "name": "has Version",
     "identifier": "dct:hasVersion",
     "usageNote": "Optional property.This property refers to a related Dataset that is a version, edition, or adaptation of the described Dataset."
   },
-  "page": {
+  {
+    "name": "documentation",
     "identifier": "foaf:page",
     "usageNote": "Optional property. This property refers to a page or document about this Dataset."
   },
-  "accessRights": {
+  {
+    "name": "access rights",
     "identifier": "dct:accessRights",
     "usageNote": "Optional property. This property refers to information that indicates whether the Dataset is open data, has access restrictions or is not public. A controlled vocabulary with three members (:public, :restricted, :non-public) will be created and maintained by the Publications Office of the EU."
   },
-  "creator": {
+  {
+    "name": "creator",
     "identifier": "dct:creator",
     "usageNote": "Optional property. This property refers to an entity primarily responsible for making the resource."
   },
-  "qualifiedAttribution": {
+  {
+    "name": "qualified attribution",
     "identifier": "prov:qualifiedAttribution",
     "usageNote": "Optional property. This property refers to the link to an Agent having some form of responsibility for the resource. "
   },
-  "wasGeneratedBy": {
+  {
+    "name": "was generated by",
     "identifier": "prov:wasGeneratedBy",
     "usageNote": "Optional property. This property refers to an activity that generated, or provides the business context for, the creation of the dataset."
   },
-  "temporalResolution": {
+  {
+    "name": "temporal resolution",
     "identifier": "dcat:temporalResolution",
     "usageNote": "This property refers to the minimum time period resolvable in the dataset."
   },
-  "spatialResolutionInMeters": {
+  {
+    "name": "spatial resolution",
     "identifier": "dcat:spatialResolutionInMeters",
     "usageNote": "Optional property. This property refers to the minimum spatial separation resolvable in a dataset, measured in meters. "
   },
-  "qualifiedRelation": {
+  {
+    "name": "qualified Relation",
     "identifier": "dcat:qualifiedRelation",
     "usageNote": "Optional property. This property provides a link to a description of a relationship with another resource."
   },
-  "isReferencedBy": {
+  {
+    "name": "is reference by",
     "identifier": "dct:isReferencedBy",
     "usageNote": "Optional property. This property refers to a related resource, such as a publication, that references, cites, or otherwise points to the dataset."
   }
-
-  
-
-
-
-
-}
\ No newline at end of file
+]
\ No newline at end of file
-- 
GitLab


From e58246ee0d36143d2da58307412720ae1b57de3f Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Thu, 1 Jul 2021 09:13:53 +0200
Subject: [PATCH 06/18] (mapping) user interface

---
 src/app/app.module.ts                         |   3 +-
 src/app/datasets/datasets.component.ts        |   8 +-
 .../elasticsearch/elasticsearch.component.ts  |  50 --------
 src/app/mapping/class/group.ts                |   9 ++
 src/app/mapping/mapping.component.html        |  39 ++++++-
 src/app/mapping/mapping.component.scss        |  24 +++-
 src/app/mapping/mapping.component.ts          | 108 +++++++++++++++---
 src/app/mapping/tree/tree.component.html      |   8 +-
 8 files changed, 170 insertions(+), 79 deletions(-)
 delete mode 100644 src/app/elasticsearch/elasticsearch.component.ts
 create mode 100644 src/app/mapping/class/group.ts

diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 367b0cca7..049072989 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -35,7 +35,7 @@ import { MappingComponent } from './mapping/mapping.component';
 import { NebularModule } from './nebular.module';
 
 import { AppRoutingModule } from './app-routing.module';
-import { NbLayoutModule, NbThemeModule, NbTooltipModule, NbSpinnerModule, NbSelectModule, NbTabsetModule } from '@nebular/theme';
+import { NbLayoutModule, NbThemeModule, NbTooltipModule, NbSpinnerModule, NbSelectModule, NbTabsetModule, NbAutocompleteModule } from '@nebular/theme';
 
 import { DashboardComponent } from './dashboard/dashboard.component';
 import { TreeComponent } from './mapping/tree/tree.component';
@@ -83,6 +83,7 @@ import { TreeComponent } from './mapping/tree/tree.component';
     NbSelectModule,
     NbTabsetModule,
     NbTooltipModule,
+    NbAutocompleteModule
   ],
 
   providers: [
diff --git a/src/app/datasets/datasets.component.ts b/src/app/datasets/datasets.component.ts
index 7b2675b5b..3ec9688ea 100644
--- a/src/app/datasets/datasets.component.ts
+++ b/src/app/datasets/datasets.component.ts
@@ -81,8 +81,8 @@ export class DatasetsComponent implements OnInit {
 
          console.log( this.itemsdataset);
 
-          this.createdataset(data);
-              //this.createdistribution(this.itemsdataset);                       
+          //this.createdataset(data);
+          //this.createdistribution(this.itemsdataset);                       
         });
     });
 
@@ -121,7 +121,7 @@ export class DatasetsComponent implements OnInit {
       a dcat:Dataset, dcat:Resource;\n\
       dct:description ' + description + ';\n\
       dct:hasVersion "1.0";\n\
-      dct:isPartOf <http://fdp-api.f2ds.svc.cluster.local/catalog/e5f49dbf-c976-4ca7-b4ee-7cc90923d9f3>;\n\
+      dct:isPartOf <https://f2ds.eosc-pillar.eu/catalog/afe472f9-2e70-409c-ad26-f174799e7834>;\n\
       dct:language language:en;\n\
       dct:license <http://rdflicense.appspot.com/rdflicense/cc-by-nc-nd3.0>;\n\
       dct:title '+ name + ';\n\
@@ -129,7 +129,7 @@ export class DatasetsComponent implements OnInit {
 
 
       console.log(data);
-   //return this.dataSetService.createDataSet(data);
+  // return this.dataSetService.createDataSet(data);
 
   }
 
diff --git a/src/app/elasticsearch/elasticsearch.component.ts b/src/app/elasticsearch/elasticsearch.component.ts
deleted file mode 100644
index b2f9e2abd..000000000
--- a/src/app/elasticsearch/elasticsearch.component.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-import { AppConfiguration } from '../AppConfiguration';
-import { HttpClient } from '@angular/common/http';
-import { FileSaverService } from 'ngx-filesaver';
-import { FormControl} from '@angular/forms';
-import { FormGroup} from '@angular/forms';
-import { Observable } from 'rxjs';
-import { environment } from 'src/environments/environment.prod';
-
-@Component({
-  selector: 'app-elasticsearch',
-  templateUrl: './elasticsearch.component.html',
-  styleUrls: ['./elasticsearch.component.scss']
-})
-export class ElasticsearchComponent implements OnInit {
-
-
-  Form = new FormGroup({
-    elasticurl: new FormControl(),
-});
-
-  constructor(
-    private appConfig: AppConfiguration,
-    private http: HttpClient,
-    private _FileSaverService: FileSaverService
-    ) {}
-
-  ngOnInit() {
-    this.Form.setValue({
-      elasticurl: this.appConfig.elasticurl  ,
-    });
-  }
-
-
-  SaveElasticsearchSetting() {
-      let data: string;
-      data ='\
-        {\n\
-          "fdpurl": "'+ this.appConfig.fdpurl +'", \n\
-          "fdpemail": "'+ this.appConfig.fdpemail +'", \n\
-          "fdppassword": "'+ this.appConfig.fdppassword +'", \n\
-          "elasticurl": "'+ this.Form.value.elasticurl +'", \n\
-          "smartapiurl": "'+ this.appConfig.smartapiurl +'" \n\
-        }'
-        console.log(data);      
-        return this.http.post("https://"+environment.apiurl+"/api/setting", data,{responseType: 'text'}).subscribe( (r)=>{console.log(r)}) ;  
-    };
-  
-
-}
diff --git a/src/app/mapping/class/group.ts b/src/app/mapping/class/group.ts
new file mode 100644
index 000000000..c280f781a
--- /dev/null
+++ b/src/app/mapping/class/group.ts
@@ -0,0 +1,9 @@
+export class Group {
+    public name: string;
+    public children: string[];
+
+    constructor(name: string, children: string[]) {
+        this.name = name;
+        this.children = children;
+    }
+}
\ No newline at end of file
diff --git a/src/app/mapping/mapping.component.html b/src/app/mapping/mapping.component.html
index 7e279ea49..04a8e2fe2 100644
--- a/src/app/mapping/mapping.component.html
+++ b/src/app/mapping/mapping.component.html
@@ -3,11 +3,46 @@
         <nb-card size="giant">
             <nb-card-header>Dataset metadata</nb-card-header>
             <nb-card-body>
-                <app-tree  [itemsDataset]="itemsdataset" [datasetModel]="datasetModel"></app-tree>
+                <div class="row">
+                    <div class="col-4">
+                        <div *ngFor="let dataset of datasetModel">
+                            <nb-form-field>
+                                <input nbInput fullWidth type="text" name="{{dataset.identifier}}"
+                                    value="{{dataset.identifier}}" disabled />
+                                <button nbSuffix nbTooltip="{{dataset.usageNote}}" nbTooltipStatus="info" nbButton
+                                    status="basic" ghost>
+                                    <nb-icon [icon]=" 'question-mark-circle-outline' " pack="eva">
+                                    </nb-icon>
+                                </button>
+                            </nb-form-field>
+                        </div>
+                    </div>
+                    <div class="col-8">
+                        <div *ngFor="let dataset of datasetModel">
+                            <nb-form-field>
+                                <input [formControl]="inputFormControl"
+                                nbInput fullWidth
+                                type="text"
+                                placeholder="Enter value"
+                                [nbAutocomplete]="auto" />
+
+                                <nb-autocomplete #auto>
+
+                                    <nb-option-group *ngFor="let group of filteredGroups | async; trackBy: trackByFn"  [title]="group.name" >
+                                        <nb-option *ngFor="let option of group.children" [value]="option">
+                                          {{ option }}
+                                        </nb-option>
+                                      </nb-option-group>
+
+                                </nb-autocomplete>
+                            </nb-form-field>
+                        </div>
+                    </div>
+                </div>
             </nb-card-body>
         </nb-card>
     </div>
-    
+
 </div>
 <div class="card-row">
     <div class="card-col">
diff --git a/src/app/mapping/mapping.component.scss b/src/app/mapping/mapping.component.scss
index d7a337d69..3867e933a 100644
--- a/src/app/mapping/mapping.component.scss
+++ b/src/app/mapping/mapping.component.scss
@@ -16,8 +16,24 @@
     margin: 0 0.5rem;
   }
 
-  .col-6 {
-    width: 50%;
-    flex: calc(50% );
-    margin: 0 0.5rem;
+  .col-4 {
+    width: 30%;
+    
+    margin-right: 10px;
+    align-items: stretch;
+  }
+
+  .col-8 {
+    width: 70%;
+    
+    margin: 10 0.5rem;
+    align-items: stretch;
+  }
+  input {
+    margin: 10px 10px;
+    
+  }
+
+  input-basic-disabled-text-color {
+    color: black;
   }
\ No newline at end of file
diff --git a/src/app/mapping/mapping.component.ts b/src/app/mapping/mapping.component.ts
index 2d65fc058..88f6fe454 100644
--- a/src/app/mapping/mapping.component.ts
+++ b/src/app/mapping/mapping.component.ts
@@ -1,16 +1,20 @@
 
-import { Component, OnInit } from '@angular/core';
-import { Observable } from 'rxjs';
+import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
+import { FormControl } from '@angular/forms';
+import { Observable, of } from 'rxjs';
+import { map, startWith } from 'rxjs/operators';
 import { AppConfiguration } from '../AppConfiguration';
 import { DatasetCrudService } from '../datasets/services/dataset-crud.service';
 import { Dataset } from './class/Dataset';
+import { Group } from './class/group';
 
 
 
 @Component({
   selector: 'app-mapping',
   templateUrl: './mapping.component.html',
-  styleUrls: ['./mapping.component.scss']
+  styleUrls: ['./mapping.component.scss'],
+
 })
 export class MappingComponent implements OnInit {
 
@@ -18,6 +22,13 @@ export class MappingComponent implements OnInit {
   itemsdataset: Object;
   datasetModel: Dataset[];
   Object = Object;
+  groups: Group[] = [];
+  filteredGroups: Observable<Group[]>;
+  inputFormControl: FormControl;
+  keychild: string = '';
+
+
+
 
   urlrepo = "https://dataverse.ird.fr";
   //  urlrepo = "data.inrae.fr";
@@ -26,27 +37,44 @@ export class MappingComponent implements OnInit {
     private appConfig: AppConfiguration,
     private dataSetService: DatasetCrudService
   ) {
-      
-    }
+
+  }
 
   ngOnInit() {
     this.itemsdataset = [];
     this.listdatasets();
     this.dataSetService.getLocally('./assets/dataset.json').subscribe(
-      dataset => this.datasetModel = dataset,
+      dataset => {
+        this.datasetModel = dataset;
+        console.log(this.datasetModel);
+
+      },
       error => console.error(error)
     );
-    
-    
+
+
+    this.filteredGroups = of(this.groups);
+    this.inputFormControl = new FormControl();
+
+    this.filteredGroups = this.inputFormControl.valueChanges
+      .pipe(
+        startWith(''),
+        map(filterString => this.filter(filterString)),
+      );
+
+
+
+
+
   }
-  
+
 
   listdatasets() {
     //appeler smart havester pour récuperer l'api à lancer
-    let params = 'api/search?q=*&per_page=5&type=dataset&start=50&show_facets=true&show_my_data=true';
+    let params = 'api/search?q=*&per_page=1&type=dataset&start=50&show_facets=true&show_my_data=true';
     this.dataSetService.getDatasetsFromApi(this.urlrepo, params).subscribe(data => {
       this.itemsdatasets = data['data']['items'];
-      
+
       for (var i = 0; i < this.itemsdatasets.length; i++) {
         if (!this.dataSetService.findDataSetByTitle(this.itemsdatasets[i]['name'])) {
           if (data['data']['items'][i]['global_id']) {
@@ -60,13 +88,16 @@ export class MappingComponent implements OnInit {
 
   populatecatalogue(id: string) {
     let params = `api/datasets/export?exporter=dataverse_json&persistentId=${id}`;
-    
+
     //appeler smart havester pour récuperer l'api à lancer
     this.dataSetService.getDatasetsFromApi(this.urlrepo, params).subscribe(data => {
       this.itemsdataset = data;
+      this.getFields(this.itemsdataset)
+
       //this.createdataset(this.itemsdataset);
       //this.createdistribution(this.itemsdataset); 
     });
+
   }
 
 
@@ -152,9 +183,56 @@ export class MappingComponent implements OnInit {
     return this.dataSetService.createDistribution(data);
   }
 
- 
 
- 
 
-  
+
+  getFields(obj: Object): Group[] {
+
+    let tab = []
+    
+    for (let key in obj) {
+
+      if (typeof obj[key] !== 'object') {
+        tab.push(key)
+      } else if (typeof obj[key] === 'object') {
+        this.groups.push(new Group(this.keychild, tab));
+        if (this.keychild === ''){
+          this.keychild = key;
+        } else {
+          this.keychild += ':' + key;
+        }
+        
+        this.getFields(obj[key]);
+      }
+    }
+
+    return this.groups;
+  }
+
+  private filterChildren(children: string[], filterValue: string) {
+    return children.filter(optionValue => optionValue.toLowerCase().includes(filterValue));
+  }
+
+  private filter(value: string): Group[] {
+    const filterValue = value.toLowerCase();
+    return this.groups
+      .map(group => {
+        return {
+          name: group.name,
+          children: this.filterChildren(group.children, filterValue),
+        }
+      })
+      .filter(group => group.children.length);
+  }
+
+  trackByFn(index, item) {
+    return item.name;
+  }
 }
+
+
+
+
+
+
+
diff --git a/src/app/mapping/tree/tree.component.html b/src/app/mapping/tree/tree.component.html
index bd2c7ad11..61393b92e 100644
--- a/src/app/mapping/tree/tree.component.html
+++ b/src/app/mapping/tree/tree.component.html
@@ -1,5 +1,5 @@
 
-<div *ngFor="let item of Object.keys(itemsDataset); let i ">
+<div *ngFor="let item of Object.keys(itemsDataset) ">
 
     <div class="row">
         
@@ -8,13 +8,15 @@
                 <h5>
                     {{item}}
                 </h5>
-                <input *ngIf="!isObject(itemsDataset[item])" type="text" value="{{itemsDataset[item]}}" disabled>
+                <input nbInput nbTooltip="This is a tooltip" nbTooltipStatus="primary" *ngIf="!isObject(itemsDataset[item])" type="text" value="{{itemsDataset[item]}}" disabled>
+            </dt>
+            <dd>
                 <nb-select [size]="size" *ngIf="!isObject(itemsDataset[item])" >
                         <nb-option value="">no value</nb-option>
                         <nb-option *ngFor="let data of datasetModel " value="{{ data.identifier}}">{{ data.name}} ({{ data.identifier}})</nb-option>
                     
                 </nb-select>
-            </dt>
+            </dd>
             
         </dl>
     </div>
-- 
GitLab


From 343b132b77248a0560db44d4b48266fc5b4b8ec1 Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Thu, 1 Jul 2021 09:40:24 +0200
Subject: [PATCH 07/18] fix(mapping)

---
 src/app/app.module.ts                       |  4 +--
 src/app/mapping/tree/tree.component.html    | 29 -------------------
 src/app/mapping/tree/tree.component.scss    | 19 ------------
 src/app/mapping/tree/tree.component.spec.ts | 25 ----------------
 src/app/mapping/tree/tree.component.ts      | 32 ---------------------
 5 files changed, 2 insertions(+), 107 deletions(-)
 delete mode 100644 src/app/mapping/tree/tree.component.html
 delete mode 100644 src/app/mapping/tree/tree.component.scss
 delete mode 100644 src/app/mapping/tree/tree.component.spec.ts
 delete mode 100644 src/app/mapping/tree/tree.component.ts

diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 049072989..135de077a 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -38,7 +38,7 @@ import { AppRoutingModule } from './app-routing.module';
 import { NbLayoutModule, NbThemeModule, NbTooltipModule, NbSpinnerModule, NbSelectModule, NbTabsetModule, NbAutocompleteModule } from '@nebular/theme';
 
 import { DashboardComponent } from './dashboard/dashboard.component';
-import { TreeComponent } from './mapping/tree/tree.component';
+
 
 
 
@@ -57,7 +57,7 @@ import { TreeComponent } from './mapping/tree/tree.component';
     StatsComponent,
     DashboardComponent,
     MappingComponent,
-    TreeComponent,
+    
     ],
   imports: [
     BrowserModule,
diff --git a/src/app/mapping/tree/tree.component.html b/src/app/mapping/tree/tree.component.html
deleted file mode 100644
index 61393b92e..000000000
--- a/src/app/mapping/tree/tree.component.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-<div *ngFor="let item of Object.keys(itemsDataset) ">
-
-    <div class="row">
-        
-        <dl>
-            <dt>
-                <h5>
-                    {{item}}
-                </h5>
-                <input nbInput nbTooltip="This is a tooltip" nbTooltipStatus="primary" *ngIf="!isObject(itemsDataset[item])" type="text" value="{{itemsDataset[item]}}" disabled>
-            </dt>
-            <dd>
-                <nb-select [size]="size" *ngIf="!isObject(itemsDataset[item])" >
-                        <nb-option value="">no value</nb-option>
-                        <nb-option *ngFor="let data of datasetModel " value="{{ data.identifier}}">{{ data.name}} ({{ data.identifier}})</nb-option>
-                    
-                </nb-select>
-            </dd>
-            
-        </dl>
-    </div>
-
-
-    <dl *ngIf="isObject(itemsDataset[item])">
-        <app-tree  [itemsDataset]="itemsDataset[item]" ></app-tree>
-    </dl>
-
-</div>
\ No newline at end of file
diff --git a/src/app/mapping/tree/tree.component.scss b/src/app/mapping/tree/tree.component.scss
deleted file mode 100644
index 72f397eed..000000000
--- a/src/app/mapping/tree/tree.component.scss
+++ /dev/null
@@ -1,19 +0,0 @@
-dl, dt, dd {
-    margin-left: 10px;
-}
-
-.row {
-    display: block;
-}
-
-input {
-    float: left;
-    width: 60%;
-    padding: 10px;
-}
-
-select {
-    float: left;
-    width: 40%;
-    padding: 10px;
-}
\ No newline at end of file
diff --git a/src/app/mapping/tree/tree.component.spec.ts b/src/app/mapping/tree/tree.component.spec.ts
deleted file mode 100644
index e3df2c328..000000000
--- a/src/app/mapping/tree/tree.component.spec.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { TreeComponent } from './tree.component';
-
-describe('TreeComponent', () => {
-  let component: TreeComponent;
-  let fixture: ComponentFixture<TreeComponent>;
-
-  beforeEach(async(() => {
-    TestBed.configureTestingModule({
-      declarations: [ TreeComponent ]
-    })
-    .compileComponents();
-  }));
-
-  beforeEach(() => {
-    fixture = TestBed.createComponent(TreeComponent);
-    component = fixture.componentInstance;
-    fixture.detectChanges();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-});
diff --git a/src/app/mapping/tree/tree.component.ts b/src/app/mapping/tree/tree.component.ts
deleted file mode 100644
index 6278c0144..000000000
--- a/src/app/mapping/tree/tree.component.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { Component, Input, OnInit } from '@angular/core';
-import { NbComponentSize } from '@nebular/theme';
-import { Observable } from 'rxjs';
-import { Dataset } from '../class/Dataset';
-
-@Component({
-  selector: 'app-tree',
-  templateUrl: './tree.component.html',
-  styleUrls: ['./tree.component.scss']
-})
-export class TreeComponent implements OnInit {
-  
-  @Input() itemsDataset;
-  @Input() datasetModel: Dataset[];
-  Object = Object;
-  size: NbComponentSize =  'medium';
-
-  constructor() { 
-
-  }
-
-  ngOnInit(): void {
-  }
-
-  isObject(object: Object): boolean{
-    if(typeof object === 'object'){
-      return true;
-    } else {
-      return false;
-    }
-  }
-}
-- 
GitLab


From 6ee79ef9e523f45bcd8c5cbe606a8b96dc8471d0 Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Tue, 6 Jul 2021 15:14:56 +0200
Subject: [PATCH 08/18] mapping: fixes

---
 src/app/datasets/services/dataset-crud.service.ts | 1 -
 src/assets/dataset.json                           | 4 ++--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/app/datasets/services/dataset-crud.service.ts b/src/app/datasets/services/dataset-crud.service.ts
index d981d8cb0..a6d1bfc9a 100644
--- a/src/app/datasets/services/dataset-crud.service.ts
+++ b/src/app/datasets/services/dataset-crud.service.ts
@@ -84,7 +84,6 @@ export class DatasetCrudService {
   }
 
   getLocally<T = any>(path: string): Observable<T> {
-    console.log('On getLocally using filepath : ', `${path}`);
     return this.http.get<T>(`${path}`);
   }
 
diff --git a/src/assets/dataset.json b/src/assets/dataset.json
index 9e96bc255..abaaa625f 100644
--- a/src/assets/dataset.json
+++ b/src/assets/dataset.json
@@ -1,7 +1,7 @@
 [
   {
-    "name": "descritpion",
-    "identifier": "dct:descritpion",
+    "name": "description",
+    "identifier": "dct:description",
     "usageNote": "Mandatory property. This property contains a free-text account of the Dataset. This property can be repeated for parallel language versions of the description."
   },
   {
-- 
GitLab


From 5b0fb761404556a73912dfb6b2545ea9bd060e20 Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Wed, 7 Jul 2021 14:26:46 +0200
Subject: [PATCH 09/18] mapping: add features & upgrade features

---
 src/app/datasets/datasets.component.ts |   2 +-
 src/app/mapping/mapping.component.html |   2 +-
 src/app/mapping/mapping.component.ts   | 122 ++++++++++++-------------
 3 files changed, 63 insertions(+), 63 deletions(-)

diff --git a/src/app/datasets/datasets.component.ts b/src/app/datasets/datasets.component.ts
index 57ac8d999..3a1e1fb54 100644
--- a/src/app/datasets/datasets.component.ts
+++ b/src/app/datasets/datasets.component.ts
@@ -82,7 +82,7 @@ export class DatasetsComponent implements OnInit {
          console.log( this.itemsdataset);
 
           this.createdataset(data);
-          //this.createdistribution(this.itemsdataset);                       
+          this.createdistribution(this.itemsdataset);                       
         });
     });
 
diff --git a/src/app/mapping/mapping.component.html b/src/app/mapping/mapping.component.html
index 700424e65..72395c52c 100644
--- a/src/app/mapping/mapping.component.html
+++ b/src/app/mapping/mapping.component.html
@@ -24,7 +24,7 @@
 
                                 <nb-form-field>
                                     <input #autoInput #{{dataset.identifier}} fullWidth id="{{dataset.identifier}}"   nbInput (input)="onChange()"
-                                    placeholder="Enter value" [nbAutocomplete]="auto" [(ngModel)]="identifiers[index]" (focus)="reset()"/>
+                                    placeholder="Enter value" [nbAutocomplete]="auto" [(ngModel)]="selectedPaths[index]" (focus)="reset()"/>
 
                                     <nb-autocomplete #auto>
 
diff --git a/src/app/mapping/mapping.component.ts b/src/app/mapping/mapping.component.ts
index 5b575662c..853dce8fd 100644
--- a/src/app/mapping/mapping.component.ts
+++ b/src/app/mapping/mapping.component.ts
@@ -1,17 +1,11 @@
 
-import { ValueConverter } from '@angular/compiler/src/render3/view/template';
 import { Component, OnInit, ViewChild } from '@angular/core';
-import { FormGroup } from '@angular/forms';
-
 import { Observable, of } from 'rxjs';
 import { map } from 'rxjs/operators';
 import { AppConfiguration } from '../AppConfiguration';
 import { DatasetCrudService } from '../datasets/services/dataset-crud.service';
 import { Dataset } from './class/Dataset';
 
-
-
-
 @Component({
   selector: 'app-mapping',
   templateUrl: './mapping.component.html',
@@ -21,46 +15,35 @@ import { Dataset } from './class/Dataset';
 export class MappingComponent implements OnInit {
 
   itemsdatasets: any;
-  itemsdataset: Object;
+  itemsdataset: Object[] = []
   datasetModel: Dataset[];
   filteredOptions: Observable<string[]>;
-  jsonTreeMap: Map<string, string> = new Map();
-  form: FormGroup
-  identifiers: string[];
-  options: string[] = [];
+  keys: string[] = [];
+  KeysMap: Map<number, string[]> = new Map();
+  selectedPaths: string[];
 
   @ViewChild('autoInput') input;
 
 
-
-
   urlrepo = "https://data.inrae.fr";
   //  urlrepo = "dataverse.ird.fr";
 
-  constructor(
-    private appConfig: AppConfiguration,
-    private dataSetService: DatasetCrudService
-  ) {
-
-  }
+  constructor(private appConfig: AppConfiguration, private dataSetService: DatasetCrudService) { }
 
   ngOnInit() {
-    this.itemsdataset = [];
     this.listdatasets();
     this.dataSetService.getLocally('./assets/dataset.json').subscribe(
       dataset => {
         this.datasetModel = dataset;
-        this.identifiers = new Array(dataset.length);
+        this.selectedPaths = new Array(dataset.length);
       },
       error => console.error(error)
     );
   }
 
-
-
   listdatasets() {
     //appeler smart havester pour récuperer l'api à lancer
-    let params = 'api/search?q=*&per_page=1&type=dataset&start=50&show_facets=true&show_my_data=true';
+    let params = 'api/search?q=*&per_page=5&type=dataset&start=50&show_facets=true&show_my_data=true';
     this.dataSetService.getDatasetsFromApi(this.urlrepo, params).subscribe(data => {
       this.itemsdatasets = data['data']['items'];
       for (var i = 0; i < this.itemsdatasets.length; i++) {
@@ -73,30 +56,29 @@ export class MappingComponent implements OnInit {
     });
   }
 
-
   populatecatalogue(id: string) {
     let params = `api/datasets/export?exporter=dataverse_json&persistentId=${id}`;
 
     //appeler smart havester pour récuperer l'api à lancer
-    this.dataSetService.getDatasetsFromApi(this.urlrepo, params).subscribe(data => {
-      this.itemsdataset = data;
-      this.getJsonTree(this.itemsdataset, '');
-      this.jsonTreeMap.forEach( (value, key) => this.options.push(key));
-      this.filteredOptions = of(this.options);
+    this.dataSetService.getDatasetsFromApi(this.urlrepo, params).subscribe((data: Object) => {
+      this.itemsdataset.push(data);
+
+      this.KeysMap.set(this.itemsdataset.length, this.getKeysFromMetadata(data, ''));
+      this.filteredOptions = of(this.keys);
     });
 
   }
 
+  createDataset(item: Object) {
+    let data: string = '';
+    let properties: string = '';
 
-
-
-  createDataset(map: Map<string, string>) {
-    let data: string;
-    let dcat: string = '';
-
-      map.forEach((value, key) => {
-          dcat += key + ' "' + value + '";\n'
-      })
+    for (let i = 0; i < this.selectedPaths.length; i++) {
+      if (this.selectedPaths[i]) {
+        let tab = this.selectedPaths[i].split('/');
+        properties += this.datasetModel[i].identifier + ' "' + this.getValue(tab, item) + '";\n'
+      }
+    }
 
     data = '\@prefix dcat: <http://www.w3.org/ns/dcat#>.\n\
             @prefix dct: <http://purl.org/dc/terms/>.\n\
@@ -104,58 +86,76 @@ export class MappingComponent implements OnInit {
             @prefix s: <'+ this.appConfig.fdpurl + '/>.\n\
             @prefix c: <'+ this.appConfig.fdpurl + '/catalog/>.\n\
             \n\
-    s:new\n' + dcat;
+    s:new\n' + properties;
 
     console.log('data: ' + data);
     //return this.dataSetService.createDataSet(data);
 
   }
 
-
+  private getValue(tab: string[], item: Object): string {
+    let obj: Object
+    for (let i = 0; i < tab.length; i++) {
+      if (tab.length == 1) {
+        return item[tab[0]];
+      } else {
+        if (i == 0) {
+          obj = item[tab[i]]
+        } else if (i < tab.length - 1) {
+          obj = obj[tab[i]];
+        } else {
+          return obj[tab[i]];
+        }
+      }
+    }
+  }
+  mapDataset() {
+    this.itemsdataset.forEach((data: Object) => {
+      this.createDataset(data);
+    })
+  }
   /* function to get recursively all the keys and values from the JSON object */
-  getJsonTree(obj: Object, keyParent: string) {
+  getKeysFromMetadata(obj: Object, keyParent: string): string[] {
 
     Object.keys(obj).forEach(key => {
       if (typeof obj[key] === 'object') {
         if (Array.isArray(obj[key])) {
           obj[key].forEach(e => {
             if (typeof e === 'object') {
-              this.getJsonTree(e, keyParent + '[\'' + key + '\']' + '[\'' + obj[key].indexOf(e) + '\']');
+              this.getKeysFromMetadata(e, keyParent + '/' + key + '/' + obj[key].indexOf(e));
             } else {
-              this.jsonTreeMap.set(keyParent + '[\'' + key + '\']' + '[\'' + obj[key].indexOf(e) + '\']', e)
+              this.keys.push(keyParent + '/' + key + '/' + obj[key].indexOf(e))
             }
           });
         } else {
-          this.getJsonTree(obj[key], keyParent + '[\'' + key + '\']');
+          if (keyParent) {
+            this.getKeysFromMetadata(obj[key], keyParent + '/' + key);
+          } else {
+            this.getKeysFromMetadata(obj[key], key);
+          }
         }
       } else {
-        this.jsonTreeMap.set(keyParent + '[\'' + key + '\']', obj[key])
+        if (keyParent) {
+          this.keys.push(keyParent + '/' + key)
+        } else {
+          this.keys.push(key)
+        }
       }
     });
+    return this.keys;
   }
-
-  mapDataset() {
-    let mappedMetadatas:Map<string, string> = new Map();
-    for (let i = 0; i < this.identifiers.length; i++) {
-      this.jsonTreeMap.forEach((value, key) => {
-        if (this.identifiers[i] === key) {
-          mappedMetadatas.set(this.datasetModel[i].identifier, value)
-         
-        }
-      })
-    }
-    this.createDataset(mappedMetadatas);
-  }
+  
 
   trackByIndex(index: number, obj: any): any {
     return index;
   }
+  
 
   /* autocompletion functions */
 
   private filter(value: string): string[] {
     let filterValue = value.toLowerCase();
-    return this.options.filter(optionValue => optionValue.toLowerCase().includes(filterValue));
+    return this.keys.filter(optionValue => optionValue.toLowerCase().includes(filterValue));
   }
 
   getFilteredOptions(value: string): Observable<string[]> {
@@ -170,7 +170,7 @@ export class MappingComponent implements OnInit {
     this.filteredOptions = this.getFilteredOptions($event);
   }
   reset() {
-    this.filteredOptions = of(this.options);
+    this.filteredOptions = of(this.keys);
   }
 
 }
-- 
GitLab


From 5701db796701d515df9ea366c8ea1a8d4f864f69 Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Thu, 8 Jul 2021 14:32:15 +0200
Subject: [PATCH 10/18] mapping: improved mapping user interface

---
 src/app/app.module.ts                  |  3 +-
 src/app/mapping/mapping.component.html | 42 +++++++++----
 src/app/mapping/mapping.component.ts   | 87 +++++++++++++++++---------
 3 files changed, 88 insertions(+), 44 deletions(-)

diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index d023bb8be..01eff55d8 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -35,7 +35,7 @@ import { MappingComponent } from './mapping/mapping.component';
 import { NebularModule } from './nebular.module';
 
 import { AppRoutingModule } from './app-routing.module';
-import { NbLayoutModule, NbThemeModule, NbTooltipModule, NbSpinnerModule, NbSelectModule, NbTabsetModule, NbAutocompleteModule } from '@nebular/theme';
+import { NbLayoutModule, NbThemeModule, NbTooltipModule, NbSpinnerModule, NbSelectModule, NbTabsetModule, NbAutocompleteModule, NbListModule } from '@nebular/theme';
 
 import { DashboardComponent } from './dashboard/dashboard.component';
 
@@ -84,6 +84,7 @@ import { DashboardComponent } from './dashboard/dashboard.component';
     NbTabsetModule,
     NbTooltipModule,
     NbAutocompleteModule,
+    NbListModule,
   ],
 
   providers: [
diff --git a/src/app/mapping/mapping.component.html b/src/app/mapping/mapping.component.html
index 72395c52c..685b10ddb 100644
--- a/src/app/mapping/mapping.component.html
+++ b/src/app/mapping/mapping.component.html
@@ -10,26 +10,26 @@
 
                             <div class="col-4">
 
-
-                                <label nbInput fullWidth type="text" for="{{dataset.identifier}}">{{dataset.identifier}}
+                                <nb-form-field>
+                                    <input nbInput fullWidth type="text" value="{{dataset.identifier}}" disabled />
                                     <button nbSuffix nbTooltip="{{dataset.name}}: {{dataset.usageNote}}"
                                         nbTooltipStatus="info" nbButton status="basic" ghost>
                                         <nb-icon [icon]=" 'question-mark-circle-outline' " pack="eva">
                                         </nb-icon>
                                     </button>
-                                </label>
+                                </nb-form-field>
 
                             </div>
                             <div class="col-8">
 
                                 <nb-form-field>
-                                    <input #autoInput #{{dataset.identifier}} fullWidth id="{{dataset.identifier}}"   nbInput (input)="onChange()"
-                                    placeholder="Enter value" [nbAutocomplete]="auto" [(ngModel)]="selectedPaths[index]" (focus)="reset()"/>
+                                    <input #autoInput #{{dataset.identifier}} fullWidth id="{{dataset.identifier}}"
+                                        nbInput (input)="onChange()" placeholder="Enter value" [nbAutocomplete]="auto"
+                                        [(ngModel)]="selectedPaths[index]" (focus)="reset()" />
 
                                     <nb-autocomplete #auto>
 
-                                        <nb-option *ngFor="let option of filteredOptions | async"
-                                            [value]="option">
+                                        <nb-option *ngFor="let option of filteredOptions | async" [value]="option">
                                             {{ option }}
                                         </nb-option>
 
@@ -49,11 +49,27 @@
     <div class="card-col">
         <nb-card>
             <nb-card-header>Map</nb-card-header>
-            <nb-card-body></nb-card-body>
+            <nb-card-body>
+                <nb-list>
+                    <nb-list-item *ngFor="let d of mappedMetadatas | keyvalue">
+                        {{d.key}} => {{d.value}}
+                    </nb-list-item>
+                </nb-list>
+
+            </nb-card-body>
+            <nb-card-footer>
+                <div class="row">
+                    <div *ngIf=" !first ">
+                        <button nbButton (click)=" prev()" [disabled]="index == 0">prev</button>
+                    </div>
+                    <div *ngIf="first">
+                        <button nbButton (click)="mapDataset()">Check mapping</button>
+                    </div>
+                    <div *ngIf="!first ">
+                        <button nbButton (click)=" next()" [disabled]="index == itemsdataset.length -1">next</button>
+                    </div>
+                </div>
+            </nb-card-footer>
         </nb-card>
     </div>
-</div>
-
-<div>
-    <button (click)="mapDataset()">test</button>
-</div>
+</div>
\ No newline at end of file
diff --git a/src/app/mapping/mapping.component.ts b/src/app/mapping/mapping.component.ts
index 853dce8fd..0d18fb0d8 100644
--- a/src/app/mapping/mapping.component.ts
+++ b/src/app/mapping/mapping.component.ts
@@ -9,8 +9,7 @@ import { Dataset } from './class/Dataset';
 @Component({
   selector: 'app-mapping',
   templateUrl: './mapping.component.html',
-  styleUrls: ['./mapping.component.scss'],
-
+  styleUrls: ['./mapping.component.scss']
 })
 export class MappingComponent implements OnInit {
 
@@ -19,9 +18,12 @@ export class MappingComponent implements OnInit {
   datasetModel: Dataset[];
   filteredOptions: Observable<string[]>;
   keys: string[] = [];
-  KeysMap: Map<number, string[]> = new Map();
+  keysMap: Map<number, string[]> = new Map();
   selectedPaths: string[];
-
+  mappedMetadatas: Map<string, string> = new Map();
+  DatasetToPublish: Map<string, string>[]; 
+  index: number = 0
+  first: boolean = true;
   @ViewChild('autoInput') input;
 
 
@@ -45,6 +47,7 @@ export class MappingComponent implements OnInit {
     //appeler smart havester pour récuperer l'api à lancer
     let params = 'api/search?q=*&per_page=5&type=dataset&start=50&show_facets=true&show_my_data=true';
     this.dataSetService.getDatasetsFromApi(this.urlrepo, params).subscribe(data => {
+      console.log(data)
       this.itemsdatasets = data['data']['items'];
       for (var i = 0; i < this.itemsdatasets.length; i++) {
         if (!this.dataSetService.findDataSetByTitle(this.itemsdatasets[i]['name'])) {
@@ -62,35 +65,44 @@ export class MappingComponent implements OnInit {
     //appeler smart havester pour récuperer l'api à lancer
     this.dataSetService.getDatasetsFromApi(this.urlrepo, params).subscribe((data: Object) => {
       this.itemsdataset.push(data);
-
-      this.KeysMap.set(this.itemsdataset.length, this.getKeysFromMetadata(data, ''));
-      this.filteredOptions = of(this.keys);
+      this.keys = [];
+      this.getKeysFromMetadata(data, '')
+      this.keysMap.set(this.itemsdataset.length, this.keys);
+      this.filteredOptions = of(this.keysMap.get(1));
     });
 
   }
 
   createDataset(item: Object) {
-    let data: string = '';
-    let properties: string = '';
+   
+
 
     for (let i = 0; i < this.selectedPaths.length; i++) {
       if (this.selectedPaths[i]) {
-        let tab = this.selectedPaths[i].split('/');
-        properties += this.datasetModel[i].identifier + ' "' + this.getValue(tab, item) + '";\n'
+        let tab = this.selectedPaths[i].split(' : ');
+        this.mappedMetadatas.set(this.datasetModel[i].identifier, this.getValue(tab, item));
       }
     }
 
-    data = '\@prefix dcat: <http://www.w3.org/ns/dcat#>.\n\
-            @prefix dct: <http://purl.org/dc/terms/>.\n\
-            @prefix language: <http://id.loc.gov/vocabulary/iso639-1/>.\n\
-            @prefix s: <'+ this.appConfig.fdpurl + '/>.\n\
-            @prefix c: <'+ this.appConfig.fdpurl + '/catalog/>.\n\
-            \n\
-    s:new\n' + properties;
+
+  }
+
+  publishDataset() {
+    let data: string = '';
+    let properties: string = '';
+
+    properties += this.mappedMetadatas.keys[this.index] + ' "' + this.mappedMetadatas.get(this.mappedMetadatas.keys[this.index]) + '";\n';
+
+      data = '\@prefix dcat: <http://www.w3.org/ns/dcat#>.\n\
+    @prefix dct: <http://purl.org/dc/terms/>.\n\
+    @prefix language: <http://id.loc.gov/vocabulary/iso639-1/>.\n\
+    @prefix s: <'+ this.appConfig.fdpurl + '/>.\n\
+    @prefix c: <'+ this.appConfig.fdpurl + '/catalog/>.\n\
+    \n\
+s:new\n' + properties;
 
     console.log('data: ' + data);
     //return this.dataSetService.createDataSet(data);
-
   }
 
   private getValue(tab: string[], item: Object): string {
@@ -110,46 +122,61 @@ export class MappingComponent implements OnInit {
     }
   }
   mapDataset() {
-    this.itemsdataset.forEach((data: Object) => {
-      this.createDataset(data);
-    })
+    this.createDataset(this.itemsdataset[this.index]);
+    this.first = false;
+  }
+  next() {
+    if (this.index < this.itemsdataset.length) {
+      this.index += 1;
+      this.createDataset(this.itemsdataset[this.index])
+      console.log('index = ' + this.index);
+    }
+  }
+  prev() {
+    this.index -= 1;
+    this.createDataset(this.itemsdataset[this.index])
+    console.log('index = ' + this.index);
   }
+
   /* function to get recursively all the keys and values from the JSON object */
-  getKeysFromMetadata(obj: Object, keyParent: string): string[] {
+  getKeysFromMetadata(obj: Object, keyParent: string) {
 
     Object.keys(obj).forEach(key => {
       if (typeof obj[key] === 'object') {
         if (Array.isArray(obj[key])) {
           obj[key].forEach(e => {
             if (typeof e === 'object') {
-              this.getKeysFromMetadata(e, keyParent + '/' + key + '/' + obj[key].indexOf(e));
+              this.getKeysFromMetadata(e, keyParent + ' : ' + key + ' : ' + obj[key].indexOf(e));
             } else {
-              this.keys.push(keyParent + '/' + key + '/' + obj[key].indexOf(e))
+              this.keys.push(keyParent + ' : ' + key + ' : ' + obj[key].indexOf(e))
             }
           });
         } else {
           if (keyParent) {
-            this.getKeysFromMetadata(obj[key], keyParent + '/' + key);
+            this.getKeysFromMetadata(obj[key], keyParent + ' : ' + key);
           } else {
             this.getKeysFromMetadata(obj[key], key);
           }
         }
       } else {
         if (keyParent) {
-          this.keys.push(keyParent + '/' + key)
+          this.keys.push(keyParent + ' : ' + key)
         } else {
           this.keys.push(key)
         }
       }
     });
-    return this.keys;
+
   }
-  
+
 
   trackByIndex(index: number, obj: any): any {
     return index;
   }
-  
+
+
+ 
+
 
   /* autocompletion functions */
 
-- 
GitLab


From 4c1c1075b0b06e5b1a5ed98a632ed084aa8d6ca8 Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Fri, 9 Jul 2021 09:26:50 +0200
Subject: [PATCH 11/18] mapping: feature to delete properties once selected

---
 src/app/mapping/mapping.component.html | 26 +++++++++++------
 src/app/mapping/mapping.component.scss | 12 ++++++++
 src/app/mapping/mapping.component.ts   | 39 ++++++++++++++++++--------
 3 files changed, 58 insertions(+), 19 deletions(-)

diff --git a/src/app/mapping/mapping.component.html b/src/app/mapping/mapping.component.html
index 685b10ddb..970249d6e 100644
--- a/src/app/mapping/mapping.component.html
+++ b/src/app/mapping/mapping.component.html
@@ -39,11 +39,14 @@
                         </div>
                     </nb-form-field>
                 </ng-container>
-
             </nb-card-body>
         </nb-card>
     </div>
-
+</div>
+<div class="row">
+    <div>
+        <button nbButton (click)="mapDataset()">Check mapping</button>
+    </div>
 </div>
 <div class="card-row">
     <div class="card-col">
@@ -51,9 +54,18 @@
             <nb-card-header>Map</nb-card-header>
             <nb-card-body>
                 <nb-list>
-                    <nb-list-item *ngFor="let d of mappedMetadatas | keyvalue">
-                        {{d.key}} => {{d.value}}
-                    </nb-list-item>
+                    
+                        <nb-list-item *ngFor="let data of mappedMetadatas[index] | keyvalue ">
+                            <div class="row">
+                                <div class="col-5">{{data.key}} : </div>
+                                <div class="col-5">{{data.value}}</div>
+                                <div class="col-2"><button nbButton ghost>
+                                        <nb-icon icon="trash-2-outline" status="danger" (click)="deleteProperty(data.key)">
+                                        </nb-icon>
+                                    </button></div>
+                            </div>
+                        </nb-list-item>
+                    
                 </nb-list>
 
             </nb-card-body>
@@ -62,9 +74,7 @@
                     <div *ngIf=" !first ">
                         <button nbButton (click)=" prev()" [disabled]="index == 0">prev</button>
                     </div>
-                    <div *ngIf="first">
-                        <button nbButton (click)="mapDataset()">Check mapping</button>
-                    </div>
+                    
                     <div *ngIf="!first ">
                         <button nbButton (click)=" next()" [disabled]="index == itemsdataset.length -1">next</button>
                     </div>
diff --git a/src/app/mapping/mapping.component.scss b/src/app/mapping/mapping.component.scss
index 3867e933a..4c11d8514 100644
--- a/src/app/mapping/mapping.component.scss
+++ b/src/app/mapping/mapping.component.scss
@@ -16,6 +16,18 @@
     margin: 0 0.5rem;
   }
 
+  .col-5 {
+    width: 45%;
+    
+    margin-right: 10px;
+    align-items: stretch;
+  }
+  .col-2 {
+    width: 10%;
+    vertical-align: middle;
+    margin-right: 10px;
+    align-items: stretch;
+  }
   .col-4 {
     width: 30%;
     
diff --git a/src/app/mapping/mapping.component.ts b/src/app/mapping/mapping.component.ts
index 0d18fb0d8..0bd54f71e 100644
--- a/src/app/mapping/mapping.component.ts
+++ b/src/app/mapping/mapping.component.ts
@@ -20,7 +20,8 @@ export class MappingComponent implements OnInit {
   keys: string[] = [];
   keysMap: Map<number, string[]> = new Map();
   selectedPaths: string[];
-  mappedMetadatas: Map<string, string> = new Map();
+  mappedMetadatas: Map<string, string>[] = [];
+  obsMappedMetadatas: Observable<Map<string, string>[]>;
   DatasetToPublish: Map<string, string>[]; 
   index: number = 0
   first: boolean = true;
@@ -41,6 +42,7 @@ export class MappingComponent implements OnInit {
       },
       error => console.error(error)
     );
+    this.obsMappedMetadatas = of(this.mappedMetadatas)
   }
 
   listdatasets() {
@@ -73,17 +75,16 @@ export class MappingComponent implements OnInit {
 
   }
 
-  createDataset(item: Object) {
-   
-
-
+  createDataset(item: Object): Map<string, string> {
+    let mappedMetadata: Map<string, string> = new Map()
     for (let i = 0; i < this.selectedPaths.length; i++) {
       if (this.selectedPaths[i]) {
         let tab = this.selectedPaths[i].split(' : ');
-        this.mappedMetadatas.set(this.datasetModel[i].identifier, this.getValue(tab, item));
+        mappedMetadata.set(this.datasetModel[i].identifier, this.getValue(tab, item));
       }
     }
-
+    
+    return mappedMetadata;
 
   }
 
@@ -91,7 +92,8 @@ export class MappingComponent implements OnInit {
     let data: string = '';
     let properties: string = '';
 
-    properties += this.mappedMetadatas.keys[this.index] + ' "' + this.mappedMetadatas.get(this.mappedMetadatas.keys[this.index]) + '";\n';
+    this.mappedMetadatas.forEach((value: Map<string, string>, key: number) => {
+      properties += value.keys[this.index] + ' "' + value.get(value.keys[this.index]) + '";\n';
 
       data = '\@prefix dcat: <http://www.w3.org/ns/dcat#>.\n\
     @prefix dct: <http://purl.org/dc/terms/>.\n\
@@ -103,6 +105,8 @@ s:new\n' + properties;
 
     console.log('data: ' + data);
     //return this.dataSetService.createDataSet(data);
+    })
+    
   }
 
   private getValue(tab: string[], item: Object): string {
@@ -113,16 +117,24 @@ s:new\n' + properties;
       } else {
         if (i == 0) {
           obj = item[tab[i]]
-        } else if (i < tab.length - 1) {
+        } else if (i < tab.length - 1 && obj[tab[i]]) {
           obj = obj[tab[i]];
         } else {
-          return obj[tab[i]];
+          if (obj[tab[i]]) {
+            return obj[tab[i]];
+          } else {
+            return 'undefined';
+          }
+          
         }
       }
     }
   }
   mapDataset() {
-    this.createDataset(this.itemsdataset[this.index]);
+    this.itemsdataset.forEach( (dataset: Object) => {
+      this.mappedMetadatas.push(this.createDataset(dataset))
+    })
+    console.log(this.mappedMetadatas)
     this.first = false;
   }
   next() {
@@ -138,6 +150,11 @@ s:new\n' + properties;
     console.log('index = ' + this.index);
   }
 
+  // to delete a property of dcat dataset mapped
+  deleteProperty(key: string) {
+    this.mappedMetadatas[this.index].delete(key);
+  }
+
   /* function to get recursively all the keys and values from the JSON object */
   getKeysFromMetadata(obj: Object, keyParent: string) {
 
-- 
GitLab


From 05cc3729fa0ac6ec995d1d8153adb3628ecfd97c Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Tue, 13 Jul 2021 13:40:48 +0200
Subject: [PATCH 12/18] mapping: get datas from previous step

---
 src/app/app-routing.module.ts                 |   1 -
 src/app/datasets/datasets.component.ts        |  16 ++-
 .../datasets/services/dataset-crud.service.ts |  49 +++++---
 src/app/mapping/mapping.component.html        |  12 +-
 src/app/mapping/mapping.component.ts          | 111 ++++++++----------
 src/app/publishapi/publishapi.component.html  |  12 +-
 src/app/publishapi/publishapi.component.ts    |   1 +
 7 files changed, 108 insertions(+), 94 deletions(-)

diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 7dba399fd..560a04624 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -30,7 +30,6 @@ const routes: ICustomRoute[] = [
         { path: 'repository', component: RepositoryComponent },
         { path: 'repositoryinfo', component: RepositoryinfoComponent },
         { path: 'accessapi', component: AccessapiComponent },
-        { path: 'datasets', component: DatasetsComponent },
         { path: 'stats', component: StatsComponent },
         { path: 'settingfdp', component: SettingfdpComponent },
         { path: 'settingsmartharvester', component: SettingsmartapiComponent },
diff --git a/src/app/datasets/datasets.component.ts b/src/app/datasets/datasets.component.ts
index 041608330..e823b558e 100644
--- a/src/app/datasets/datasets.component.ts
+++ b/src/app/datasets/datasets.component.ts
@@ -1,4 +1,4 @@
-import { Component, Input, OnInit } from '@angular/core';
+import { Component, Input, OnInit, Output } from '@angular/core';
 import { AppConfiguration } from '../AppConfiguration';
 import { DatasetCrudService } from './services/dataset-crud.service';
 import { OpenApi } from '../publishapi/class/openapi';
@@ -27,8 +27,8 @@ export class DatasetsComponent implements OnInit {
   previews = new Map<string, any>();
   spinners = new Map<string, boolean>();
 
-  itemsdatasets: any;
-  itemsdataset: any;
+  
+ 
   Object = Object;
 
   //urlrepo = "dataverse.ird.fr";
@@ -44,7 +44,8 @@ export class DatasetsComponent implements OnInit {
   }
 
   ngOnInit() {
-    this.itemsdataset = [];
+    this.dataSetService.itemsDataset = [];
+    
   }
 
   ngOnChanges() {
@@ -119,6 +120,9 @@ export class DatasetsComponent implements OnInit {
             break;
           case OpenApiTag.dataset:
             this.processDataSet(data, pathName, preview);
+            if (response.status.toString().startsWith('2'))
+            this.dataSetService.saveDatasets(data);
+            console.log(this.dataSetService.itemsDataset)
           break;
         }
       }).finally(() => this.spinners.set(pathName, false));
@@ -215,7 +219,7 @@ export class DatasetsComponent implements OnInit {
     return null;
   }
 
-  listdatasets() {
+  /*listdatasets() {
     var myHeaders = new Headers();
     myHeaders.append("Content-Type", "Application/json");
     var myInit = { method: 'GET', headers: myHeaders };
@@ -353,7 +357,7 @@ export class DatasetsComponent implements OnInit {
 
     return this.dataSetService.createDistribution(data);
 
-  }
+  }*/
 
 
 
diff --git a/src/app/datasets/services/dataset-crud.service.ts b/src/app/datasets/services/dataset-crud.service.ts
index a6d1bfc9a..74692eb03 100644
--- a/src/app/datasets/services/dataset-crud.service.ts
+++ b/src/app/datasets/services/dataset-crud.service.ts
@@ -12,30 +12,38 @@ import { ParseXmlService } from '../../services/parse-xml.service';
 export class DatasetCrudService {
 
   fds2Token: string
-  public results: string[] = [];   
+  public results: string[] = [];  
+  itemsDataset: Object[] = [] ;
   constructor(private http: HttpClient,private appConfig: AppConfiguration, private authService: AuthService, private parserService: ParseXmlService) { }
 
   createDataSet(data:string){
 
-    this.authService.getF2DSAuthToken().subscribe(data=>{
-      this.fds2Token = data.token
-    })
-    if (this.fds2Token) {
-      const httpOptions = {
-        headers: new HttpHeaders({
-          'Accept':  'text/turtle',
-          'Content-Type':  'text/turtle',
-          'Authorization': 'Bearer '+ this.fds2Token
-        })
-      };
-      
-      let resultat = this.http.post(this.appConfig.fdpurl+"/dataset", data, httpOptions ).subscribe( (r)=>{console.log('reponse: ', r)}) ;
-      if (resultat){
-        console.log("resultat: " + JSON.stringify(resultat));
-        return JSON.stringify(resultat);
+    this.authService.getF2DSAuthToken().subscribe(token=>{
+      this.fds2Token = token.token
+      if (this.fds2Token) {
+        const httpOptions = {
+          headers: new HttpHeaders({
+            'Accept':  'text/turtle',
+            'Content-Type':  'text/turtle',
+            'Authorization': 'Bearer '+ this.fds2Token
+          })
+        };
+        
+        this.http.post(this.appConfig.fdpurl+"/dataset", data, httpOptions ).subscribe(
+           (r)=>{
+          if (r){
+            console.log("resultat: " + JSON.stringify(r));
+            
+          }
+          
+        },
+        error => console.error("The repository has not been published") 
+        
+        ) ;
+       
       }
-      return "The repository has not been published"
-    }
+    })
+    
   }
 
   createDistribution(data:string){
@@ -86,6 +94,9 @@ export class DatasetCrudService {
   getLocally<T = any>(path: string): Observable<T> {
     return this.http.get<T>(`${path}`);
   }
+  saveDatasets(obj: Object) {
+    this.itemsDataset.push(obj);
+  }
 
 
 }
diff --git a/src/app/mapping/mapping.component.html b/src/app/mapping/mapping.component.html
index 970249d6e..0ad1f4190 100644
--- a/src/app/mapping/mapping.component.html
+++ b/src/app/mapping/mapping.component.html
@@ -1,6 +1,9 @@
 <div class="card-row">
     <div class="card-col">
-        <nb-card size="giant">
+        <nb-card size="giant" [nbSpinner]="loading"
+        nbSpinnerStatus="primary"
+             nbSpinnerSize="large"
+             nbSpinnerMessage="Loading...">
             <nb-card-header>Dataset metadata</nb-card-header>
             <nb-card-body>
                 <div></div>
@@ -50,7 +53,7 @@
 </div>
 <div class="card-row">
     <div class="card-col">
-        <nb-card>
+        <nb-card >
             <nb-card-header>Map</nb-card-header>
             <nb-card-body>
                 <nb-list>
@@ -76,7 +79,10 @@
                     </div>
                     
                     <div *ngIf="!first ">
-                        <button nbButton (click)=" next()" [disabled]="index == itemsdataset.length -1">next</button>
+                        <button nbButton (click)=" next()" [disabled]="index == mappedMetadatas.length -1">next</button>
+                    </div>
+                    <div *ngIf="!first ">
+                        <button nbButton (click)=" publishDataset()">Publish</button>
                     </div>
                 </div>
             </nb-card-footer>
diff --git a/src/app/mapping/mapping.component.ts b/src/app/mapping/mapping.component.ts
index 0bd54f71e..27239c7d3 100644
--- a/src/app/mapping/mapping.component.ts
+++ b/src/app/mapping/mapping.component.ts
@@ -1,5 +1,5 @@
 
-import { Component, OnInit, ViewChild } from '@angular/core';
+import { Component, Input, OnInit, ViewChild } from '@angular/core';
 import { Observable, of } from 'rxjs';
 import { map } from 'rxjs/operators';
 import { AppConfiguration } from '../AppConfiguration';
@@ -13,7 +13,7 @@ import { Dataset } from './class/Dataset';
 })
 export class MappingComponent implements OnInit {
 
-  itemsdatasets: any;
+
   itemsdataset: Object[] = []
   datasetModel: Dataset[];
   filteredOptions: Observable<string[]>;
@@ -22,57 +22,44 @@ export class MappingComponent implements OnInit {
   selectedPaths: string[];
   mappedMetadatas: Map<string, string>[] = [];
   obsMappedMetadatas: Observable<Map<string, string>[]>;
-  DatasetToPublish: Map<string, string>[]; 
+  DatasetToPublish: Map<string, string>[];
   index: number = 0
   first: boolean = true;
+  loading: boolean = false;
   @ViewChild('autoInput') input;
-
-
-  urlrepo = "https://data.inrae.fr";
-  //  urlrepo = "dataverse.ird.fr";
+  @Input() catalogId: any;
 
   constructor(private appConfig: AppConfiguration, private dataSetService: DatasetCrudService) { }
 
+
   ngOnInit() {
-    this.listdatasets();
     this.dataSetService.getLocally('./assets/dataset.json').subscribe(
       dataset => {
         this.datasetModel = dataset;
         this.selectedPaths = new Array(dataset.length);
       },
-      error => console.error(error)
+      error => {
+        console.error(error);
+      },
     );
+
     this.obsMappedMetadatas = of(this.mappedMetadatas)
+    this.populatecatalogue();
   }
 
-  listdatasets() {
-    //appeler smart havester pour récuperer l'api à lancer
-    let params = 'api/search?q=*&per_page=5&type=dataset&start=50&show_facets=true&show_my_data=true';
-    this.dataSetService.getDatasetsFromApi(this.urlrepo, params).subscribe(data => {
-      console.log(data)
-      this.itemsdatasets = data['data']['items'];
-      for (var i = 0; i < this.itemsdatasets.length; i++) {
-        if (!this.dataSetService.findDataSetByTitle(this.itemsdatasets[i]['name'])) {
-          if (data['data']['items'][i]['global_id']) {
-            this.populatecatalogue(data['data']['items'][i]['global_id']);
-          }
-        }
-      }
-    });
-  }
 
-  populatecatalogue(id: string) {
-    let params = `api/datasets/export?exporter=dataverse_json&persistentId=${id}`;
 
-    //appeler smart havester pour récuperer l'api à lancer
-    this.dataSetService.getDatasetsFromApi(this.urlrepo, params).subscribe((data: Object) => {
-      this.itemsdataset.push(data);
-      this.keys = [];
-      this.getKeysFromMetadata(data, '')
-      this.keysMap.set(this.itemsdataset.length, this.keys);
-      this.filteredOptions = of(this.keysMap.get(1));
-    });
 
+  populatecatalogue() {
+    this.itemsdataset = this.dataSetService.itemsDataset;
+    this.keys = [];
+    for (let i = 0; i< this.itemsdataset.length; i++){
+      if (i === 0) {
+        this.getKeysFromMetadata(this.itemsdataset[i], '');
+        this.keysMap.set(this.itemsdataset.length, this.keys);
+        this.filteredOptions = of(this.keysMap.get(1));
+      }
+    }
   }
 
   createDataset(item: Object): Map<string, string> {
@@ -83,31 +70,41 @@ export class MappingComponent implements OnInit {
         mappedMetadata.set(this.datasetModel[i].identifier, this.getValue(tab, item));
       }
     }
-    
+
     return mappedMetadata;
 
   }
 
-  publishDataset() {
-    let data: string = '';
-    let properties: string = '';
-
-    this.mappedMetadatas.forEach((value: Map<string, string>, key: number) => {
-      properties += value.keys[this.index] + ' "' + value.get(value.keys[this.index]) + '";\n';
+  
 
-      data = '\@prefix dcat: <http://www.w3.org/ns/dcat#>.\n\
-    @prefix dct: <http://purl.org/dc/terms/>.\n\
-    @prefix language: <http://id.loc.gov/vocabulary/iso639-1/>.\n\
-    @prefix s: <'+ this.appConfig.fdpurl + '/>.\n\
-    @prefix c: <'+ this.appConfig.fdpurl + '/catalog/>.\n\
-    \n\
-s:new\n' + properties;
+publishDataset() {
+  let data: string = '';
+  let properties: string = '';
 
-    console.log('data: ' + data);
-    //return this.dataSetService.createDataSet(data);
+  this.mappedMetadatas.forEach((value: Map<string, string>, key: number) => {
+    properties = "";
+    value.forEach( (value: string, key: string) => {
+     
+      properties += key+ ' "' + value + '";\n';
     })
-    
-  }
+   
+
+    data = '\@prefix dcat: <http://www.w3.org/ns/dcat#>.\n\
+  @prefix dct: <http://purl.org/dc/terms/>.\n\
+  @prefix language: <http://id.loc.gov/vocabulary/iso639-1/>.\n\
+  @prefix s: <'+ this.appConfig.fdpurl + '/>.\n\
+  @prefix c: <'+ this.appConfig.fdpurl + '/catalog/>.\n\
+  \n\
+s:new\n\
+a dcat:Dataset, dcat:Resource;\n\
+dct:isPartOf c:'+ this.catalogId + ';\n' + properties + '.';
+
+  console.log('data: ' + data);
+  this.dataSetService.createDataSet(data);
+  })
+  
+}
+ 
 
   private getValue(tab: string[], item: Object): string {
     let obj: Object
@@ -125,13 +122,14 @@ s:new\n' + properties;
           } else {
             return 'undefined';
           }
-          
+
         }
       }
     }
   }
   mapDataset() {
-    this.itemsdataset.forEach( (dataset: Object) => {
+    this.mappedMetadatas = [];
+    this.itemsdataset.forEach((dataset: Object) => {
       this.mappedMetadatas.push(this.createDataset(dataset))
     })
     console.log(this.mappedMetadatas)
@@ -186,15 +184,10 @@ s:new\n' + properties;
 
   }
 
-
   trackByIndex(index: number, obj: any): any {
     return index;
   }
 
-
- 
-
-
   /* autocompletion functions */
 
   private filter(value: string): string[] {
diff --git a/src/app/publishapi/publishapi.component.html b/src/app/publishapi/publishapi.component.html
index 0fd440c98..693ef4e73 100644
--- a/src/app/publishapi/publishapi.component.html
+++ b/src/app/publishapi/publishapi.component.html
@@ -4,7 +4,7 @@
 
 <nb-card>
   <nb-card-body>
-    <nb-stepper orientation="horizontal" disableStepNavigation>
+    <nb-stepper orientation="horizontal" disableStepNavigation >
       <nb-step [label]="labelOne">
         <ng-template #labelOne>First step</ng-template>
         <h4>Describe API</h4>
@@ -292,16 +292,16 @@
         <h4>Use parameters & launch request</h4>
         <app-datasets [openApi]="openApi"></app-datasets>
         <button class="prev-button" nbButton nbStepperPrevious>prev</button>
-        <button class="next-button" nbButton nbStepperNext>next</button>
+        <button class="next-button" nbButton nbStepperNext (click)="initLabelThree = true">next</button>
       </nb-step>
-      <nb-step [label]="labelThree">
+      <nb-step [label]="labelThree" >
         <ng-template #labelThree>Third step</ng-template>
         <h4>Map DCAT Schema </h4>
         <p class="lorem">
           Map your metadata schema with DCAT schema
-        </p>
-        <app-mapping></app-mapping>
-        <button class="prev-button" nbButton nbStepperPrevious>prev</button>
+        </p> 
+          <app-mapping *ngIf="initLabelThree" [catalogId]="openApi.info['x-catalog-id']"></app-mapping>
+        <button class="prev-button" nbButton nbStepperPrevious (click)="initLabelThree = false">prev</button>
         <button class="next-button" nbButton nbStepperNext>next</button>
       </nb-step>
       <nb-step [label]="labelFour">
diff --git a/src/app/publishapi/publishapi.component.ts b/src/app/publishapi/publishapi.component.ts
index 085fbae77..3a3cf8853 100644
--- a/src/app/publishapi/publishapi.component.ts
+++ b/src/app/publishapi/publishapi.component.ts
@@ -31,6 +31,7 @@ export class PublishApiComponent implements OnInit {
   httpStatusCodes: string[];
   catalogList: { title: string, catId: string, server: string }[] = [];
   canNext = false;
+  initLabelThree: boolean = false;
 
   ngOnInit(): void {
     this.openApi = new OpenApi(null, null);
-- 
GitLab


From 13bc51e05f34e27915366d7bae8a025d9a7e83bd Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Tue, 13 Jul 2021 17:08:19 +0200
Subject: [PATCH 13/18] mapping: small fix

---
 .../datasets/services/dataset-crud.service.ts | 31 ++++++-------------
 1 file changed, 10 insertions(+), 21 deletions(-)

diff --git a/src/app/datasets/services/dataset-crud.service.ts b/src/app/datasets/services/dataset-crud.service.ts
index 74692eb03..cafd63ee3 100644
--- a/src/app/datasets/services/dataset-crud.service.ts
+++ b/src/app/datasets/services/dataset-crud.service.ts
@@ -2,7 +2,7 @@ import { HttpClient, HttpHeaders } from '@angular/common/http';
 import { Injectable } from '@angular/core';
 import { Observable } from 'rxjs';
 import { AppConfiguration } from 'src/app/AppConfiguration';
-import { AuthService } from 'src/app/authentication/services/auth.service';
+import { TokenStorageService } from 'src/app/authentication/services/token-storage.service';
 import { ParseXmlService } from '../../services/parse-xml.service';
 
 
@@ -11,15 +11,12 @@ import { ParseXmlService } from '../../services/parse-xml.service';
 })
 export class DatasetCrudService {
 
-  fds2Token: string
+  fds2Token: string = this.sessionStorage.getFDPToken();
   public results: string[] = [];  
   itemsDataset: Object[] = [] ;
-  constructor(private http: HttpClient,private appConfig: AppConfiguration, private authService: AuthService, private parserService: ParseXmlService) { }
+  constructor(private http: HttpClient,private appConfig: AppConfiguration, private parserService: ParseXmlService, private sessionStorage: TokenStorageService) { }
 
   createDataSet(data:string){
-
-    this.authService.getF2DSAuthToken().subscribe(token=>{
-      this.fds2Token = token.token
       if (this.fds2Token) {
         const httpOptions = {
           headers: new HttpHeaders({
@@ -29,28 +26,21 @@ export class DatasetCrudService {
           })
         };
         
-        this.http.post(this.appConfig.fdpurl+"/dataset", data, httpOptions ).subscribe(
-           (r)=>{
-          if (r){
+        this.http.post(this.appConfig.fdpurl+"/dataset", data, httpOptions ).subscribe( r => {
             console.log("resultat: " + JSON.stringify(r));
-            
-          }
-          
         },
-        error => console.error("The repository has not been published") 
+        error => console.error("The repository has not been published: " + error) ,
+        () => console.log("The datasets has benn published")
         
         ) ;
        
       }
-    })
+    
     
   }
 
   createDistribution(data:string){
 
-    this.authService.getF2DSAuthToken().subscribe(data=>{
-      this.fds2Token = data.token
-    })
     if (this.fds2Token) {
       const httpOptions = {
         headers: new HttpHeaders({
@@ -60,11 +50,10 @@ export class DatasetCrudService {
         })
       };
       
-      let resultat = this.http.post(this.appConfig.fdpurl+"/distribution", data, httpOptions ).subscribe( (r)=>{console.log('reponse: ', r)}) ;
-      if (resultat){
-        console.log("resultat: " + JSON.stringify(resultat));
+      let resultat = this.http.post(this.appConfig.fdpurl+"/distribution", data, httpOptions ).subscribe((r)=>{
+        console.log('reponse: ', r);
         return JSON.stringify(resultat);
-      }
+      }) ;
     }
   }
 
-- 
GitLab


From 1935e8d27a649067e74a9d7408b49fa1b61c67b1 Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Thu, 15 Jul 2021 15:43:32 +0200
Subject: [PATCH 14/18] fix token management and logout feature

---
 src/app/app-routing.module.ts                 |  3 +-
 .../authentication/services/auth.service.ts   | 32 +++++++++++++------
 .../services/token-storage.service.ts         |  2 ++
 .../authentication/signin/signin.component.ts | 16 ++++++----
 .../authentication/signup/signup.component.ts |  2 +-
 src/app/dashboard/dashboard.component.html    |  5 +--
 src/app/dashboard/dashboard.component.scss    |  3 ++
 src/app/dashboard/dashboard.component.ts      |  7 ++++
 src/app/repository/repository.component.ts    |  2 +-
 .../services/publish-repository.service.ts    | 11 +++----
 src/app/user/model/user.ts                    | 10 +++++-
 11 files changed, 63 insertions(+), 30 deletions(-)

diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 560a04624..292358d56 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -1,9 +1,8 @@
 import { NgModule } from '@angular/core';
-import { Routes, RouterModule, Route } from '@angular/router';
+import { RouterModule, Route } from '@angular/router';
 import { UserComponent } from './user/user.component';
 import { RepositoryComponent } from './repository/repository.component';
 import { AccessapiComponent } from './accessapi/accessapi.component';
-import { DatasetsComponent } from './datasets/datasets.component';
 import { SettingfdpComponent } from './settingfdp/settingfdp.component';
 import { SettingsmartapiComponent } from './settingsmartapi/settingsmartapi.component';
 import { RepositoryinfoComponent } from './repositoryinfo/repositoryinfo.component';
diff --git a/src/app/authentication/services/auth.service.ts b/src/app/authentication/services/auth.service.ts
index 13de15a0c..6c88d160a 100644
--- a/src/app/authentication/services/auth.service.ts
+++ b/src/app/authentication/services/auth.service.ts
@@ -2,23 +2,29 @@ import { HttpClient, HttpHeaders } from '@angular/common/http';
 import { Injectable } from '@angular/core';
 import { Observable } from 'rxjs';
 import { TokenStorageService } from './token-storage.service';
-import { map } from "rxjs/operators";
 import { AppConfiguration } from 'src/app/AppConfiguration';
-import { env } from 'process';
 import { environment } from 'src/environments/environment';
 
 
+
+
 const AUTH_API = environment.smartharvesterUrl + '/harvester/auth';
 const httpOptions = {
   headers: new HttpHeaders({ 'Content-Type': 'application/json' })
 };
 
+
 @Injectable({
   providedIn: 'root'
 })
 export class AuthService {
 
-  constructor(private http: HttpClient, private tokenService: TokenStorageService, private appConfig:AppConfiguration) { }
+
+
+  constructor(private http: HttpClient, private tokenService: TokenStorageService, private appConfig: AppConfiguration) { }
+
+
+
 
   login(credentials): Observable<any> {
     let data: any
@@ -41,16 +47,16 @@ export class AuthService {
 
   update(user): Observable<any> {
     return this.http.post(AUTH_API + '/user', {
-       catalog_id: user.cat_id
+      catalog_id: user.cat_id
     }, httpOptions);
   }
 
 
-  getF2DSAuthToken():Observable<any> {
-     return this.http.post(this.appConfig.fdpurl+'/tokens', {
-        email: this.appConfig.fdpemail,
-        password:  this.appConfig.fdppassword
-      },httpOptions);
+  getF2DSAuthToken(credentials): Observable<any> {
+    return this.http.post(this.appConfig.fdpurl + '/tokens', {
+      email: credentials.email,
+      password: credentials.password
+    }, httpOptions);
   }
 
   public isLoggedIn() {
@@ -58,6 +64,12 @@ export class AuthService {
   }
 
   public logout() {
-    this.tokenService.removeToken();
+    const config = {
+      headers: new HttpHeaders({
+        'Content-Type': 'application/x-www-form-urlencoded'
+      })
+    };
+    this.tokenService.signOut();
+    return this.http.post(`${environment.smartharvesterUrl}/logout`, null, config);
   }
 }
diff --git a/src/app/authentication/services/token-storage.service.ts b/src/app/authentication/services/token-storage.service.ts
index 4acab50b5..5efd47144 100644
--- a/src/app/authentication/services/token-storage.service.ts
+++ b/src/app/authentication/services/token-storage.service.ts
@@ -17,6 +17,7 @@ export class TokenStorageService {
 
   public saveToken(token: string,f2dsToken:string): void {
     window.sessionStorage.removeItem(TOKEN_KEY);
+    window.sessionStorage.removeItem(F2DS_TOKEN_KEY);
     window.sessionStorage.setItem(TOKEN_KEY, token);
     window.sessionStorage.setItem(F2DS_TOKEN_KEY, f2dsToken);
   }
@@ -38,6 +39,7 @@ export class TokenStorageService {
   }
   public removeToken(){
     window.localStorage.removeItem(TOKEN_KEY);
+    window.sessionStorage.removeItem(F2DS_TOKEN_KEY);
   }
 
   
diff --git a/src/app/authentication/signin/signin.component.ts b/src/app/authentication/signin/signin.component.ts
index ba61f6ab1..63f28e0f3 100644
--- a/src/app/authentication/signin/signin.component.ts
+++ b/src/app/authentication/signin/signin.component.ts
@@ -21,7 +21,7 @@ export class SigninComponent implements OnInit {
   isLoginFailed = false;
   errorMessage = '';
   showPassword = false;
-  user: SmartHarvesterUser = new SmartHarvesterUser();
+  user: SmartHarvesterUser = new SmartHarvesterUser({});
   
 
   constructor(private authService: AuthService, private router: Router, private tokenStorage: TokenStorageService) { }
@@ -31,27 +31,29 @@ export class SigninComponent implements OnInit {
       // Uncomment line to avoid re-authentication if token is still valid
       //this.isLoggedIn = true;
     }
-    this.authService.getF2DSAuthToken().subscribe((response:F2DSResponse) => {
-      if (response) this.f2dsToken = response.token;
-      console.log("F2ds token is : ", this.f2dsToken)
-    })
+    
   }
 
   //get formControls() { return this.formGroup.controls; }
 
   onSubmit(): void {
 
-
+    
 
     this.authService.login(this.user).subscribe(
       data => {
-        this.tokenStorage.saveToken(data.accessToken, this.f2dsToken);
+        this.authService.getF2DSAuthToken(this.user).subscribe((response:F2DSResponse) => {
+          if (response) this.f2dsToken = response.token;
+          console.log("F2ds token is : ", this.f2dsToken);
+          this.tokenStorage.saveToken(data.accessToken, this.f2dsToken);
         this.tokenStorage.saveUser(data);
 
         this.isLoginFailed = false;
         this.isLoggedIn = true;
         console.log("User data : ", data)
         this.router.navigateByUrl('/dashboard');
+        })
+        
         //this.reloadPage();
       },
       err => {
diff --git a/src/app/authentication/signup/signup.component.ts b/src/app/authentication/signup/signup.component.ts
index b9e374291..8a757692f 100644
--- a/src/app/authentication/signup/signup.component.ts
+++ b/src/app/authentication/signup/signup.component.ts
@@ -16,7 +16,7 @@ export class SignupComponent implements OnInit {
   isLoginFailed = false;
   errorMessage = '';
   showPassword = false;
-  user: SmartHarvesterUser = new SmartHarvesterUser();
+  user: SmartHarvesterUser = new SmartHarvesterUser({});
   
   
   constructor(private authService: AuthService, private router: Router) { }
diff --git a/src/app/dashboard/dashboard.component.html b/src/app/dashboard/dashboard.component.html
index 439aa3d7b..57e29c2f9 100644
--- a/src/app/dashboard/dashboard.component.html
+++ b/src/app/dashboard/dashboard.component.html
@@ -4,9 +4,10 @@
         <a routerLink="/dashboard" routerLinkActive="active">
           <img width="80" alt="Angular Logo" src="assets/images/logo.png" />
         </a>
-       
+        <h3 style="width: 100%;text-align: center;"> <strong></strong></h3>
   
         <!--User badge-->
+        
         <nb-user style="white-space: pre;" 
                  name="{{userData.firstName}}" 
                  title="{{userData.lastName}}"
@@ -14,7 +15,7 @@
                  nbContextMenuTag="my-context-menu" 
                  badgePosition="right">
         </nb-user>
-        <!--<button routerLink="/login" nbContextMenuPlacement="right" outline nbButton>Login</button>-->
+        <button (click)="logout()" nbContextMenuPlacement="right" outline nbButton>Logout</button>
   
       </nb-layout-header>
   
diff --git a/src/app/dashboard/dashboard.component.scss b/src/app/dashboard/dashboard.component.scss
index e69de29bb..10fd21b25 100644
--- a/src/app/dashboard/dashboard.component.scss
+++ b/src/app/dashboard/dashboard.component.scss
@@ -0,0 +1,3 @@
+button {
+    margin-left: 10px;
+}
\ No newline at end of file
diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts
index ebcd85424..83fdcceab 100644
--- a/src/app/dashboard/dashboard.component.ts
+++ b/src/app/dashboard/dashboard.component.ts
@@ -91,4 +91,11 @@ export class DashboardComponent implements OnInit {
     this.sidebarService.toggle(true);
     return false;
   }
+
+  logout() {
+    this.authService.logout().subscribe(
+      value => this.route.navigateByUrl('/auth/signin')
+    );
+
+  }
 }
diff --git a/src/app/repository/repository.component.ts b/src/app/repository/repository.component.ts
index e9c83cc6e..00a7335ae 100644
--- a/src/app/repository/repository.component.ts
+++ b/src/app/repository/repository.component.ts
@@ -43,7 +43,7 @@ export class RepositoryComponent implements OnInit {
   ) { }
 
   ngOnInit() {
-    this.authService.getF2DSAuthToken();
+   
     this.publishService.getPersistentUrl().subscribe({
       next: (response) => this.persistentUrl = response.persistentUrl
     });
diff --git a/src/app/repository/services/publish-repository.service.ts b/src/app/repository/services/publish-repository.service.ts
index 84dca3fab..913909bbc 100644
--- a/src/app/repository/services/publish-repository.service.ts
+++ b/src/app/repository/services/publish-repository.service.ts
@@ -15,6 +15,7 @@ interface PersistentUrlResponse {
   providedIn: 'root'
 })
 export class PublishRepositoryService {
+  fds2Token: string = this.tokenService.getFDPToken();
 
   constructor(
     private http: HttpClient,
@@ -29,14 +30,12 @@ export class PublishRepositoryService {
 
   publishRepository(data: string) {
 
-    this.authService.getF2DSAuthToken().subscribe(tokenResponse => {
-      const fds2Token = tokenResponse.token;
-      if (fds2Token) {
+      if (this.fds2Token) {
 
         const myHeaders = new Headers();
         myHeaders.append('Accept', 'text/turtle');
         myHeaders.append('Content-Type', 'text/turtle');
-        myHeaders.append('Authorization', 'Bearer ' + fds2Token);
+        myHeaders.append('Authorization', 'Bearer ' + this.fds2Token);
         const myInit = { method: 'POST', body: data, headers: myHeaders };
 
         const myRequest = new Request(this.appConfig.fdpurl + "/catalog", myInit);
@@ -53,7 +52,7 @@ export class PublishRepositoryService {
 
         return "The repository has not been published"
       }
-    });
+    
   }
 
   getPersistentUrl(): Observable<PersistentUrlResponse> {
@@ -61,7 +60,7 @@ export class PublishRepositoryService {
   }
 
   async addUserCatalog(catId: string): Promise<any> {
-    const tokenResponse = this.tokenService.getToken;
+    const tokenResponse = this.tokenService.getToken();
     const user = this.tokenService.getUser();
 
     return this.http.post(this.smartApiUrl + '/user/' + user.email + '/catalogs', catId,
diff --git a/src/app/user/model/user.ts b/src/app/user/model/user.ts
index ad90ab747..fbd9c6fd1 100644
--- a/src/app/user/model/user.ts
+++ b/src/app/user/model/user.ts
@@ -6,5 +6,13 @@ export class SmartHarvesterUser {
     public passwordConfirm?: string;
     public id?: "5fbfb86b688c8577c7b8aeff"
     public token?: "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ0ZXN0QGNpbmVzLmZyIiwiaWF0IjoxNjA2ODQzNjkwLCJleHAiOjE2MDY5MzAwOTB9.UcmKMRmIEyNLW_kCEEI83uMuDG3Lgf5BKeAHvOhhjiFsV-8keKXxy5VLyHR4LvX_7vZL9WN_H_49-sLxGFTJyQ"
-    public tokenType?: "Bearer"
+    public tokenType?: "Bearer";
+
+    constructor(params: any) {
+        Object.assign(this, params);
+    }
+
+    isAnonyme(): boolean {
+        return this.email === undefined;
+      }
 }
-- 
GitLab


From 74756c940d8945df5ce026f86c5df2541ec42916 Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Thu, 15 Jul 2021 15:54:36 +0200
Subject: [PATCH 15/18] fix logout path

---
 src/app/authentication/services/auth.service.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/app/authentication/services/auth.service.ts b/src/app/authentication/services/auth.service.ts
index 6c88d160a..be1686c49 100644
--- a/src/app/authentication/services/auth.service.ts
+++ b/src/app/authentication/services/auth.service.ts
@@ -70,6 +70,6 @@ export class AuthService {
       })
     };
     this.tokenService.signOut();
-    return this.http.post(`${environment.smartharvesterUrl}/logout`, null, config);
+    return this.http.post(`${AUTH_API}/logout`, null, config);
   }
 }
-- 
GitLab


From 0f653d5035aebc88f77f8482d953eb8f74d2df14 Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Fri, 16 Jul 2021 09:03:27 +0200
Subject: [PATCH 16/18] delete fdp & smartharvester settings: config from
 environement and get user connected to provide tokens

---
 src/app/app-routing.module.ts                             | 4 ++--
 src/app/authentication/services/auth.service.ts           | 3 ++-
 src/app/dashboard/dashboard.component.ts                  | 4 ++--
 src/app/datasets/datasets.component.ts                    | 6 ++++--
 src/app/datasets/services/dataset-crud.service.ts         | 7 ++++---
 src/app/mapping/mapping.component.ts                      | 6 ++++--
 src/app/repository/repository.component.ts                | 3 ++-
 src/app/repository/services/publish-repository.service.ts | 4 ++--
 src/app/services/catalog.service.ts                       | 4 +++-
 9 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 292358d56..a78e3ca46 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -30,8 +30,8 @@ const routes: ICustomRoute[] = [
         { path: 'repositoryinfo', component: RepositoryinfoComponent },
         { path: 'accessapi', component: AccessapiComponent },
         { path: 'stats', component: StatsComponent },
-        { path: 'settingfdp', component: SettingfdpComponent },
-        { path: 'settingsmartharvester', component: SettingsmartapiComponent },
+       /* { path: 'settingfdp', component: SettingfdpComponent },
+        { path: 'settingsmartharvester', component: SettingsmartapiComponent },*/
         { path: 'publishapi', component: PublishApiComponent },
         { path: 'advancedsearch', component: SearchComponent },
       ]
diff --git a/src/app/authentication/services/auth.service.ts b/src/app/authentication/services/auth.service.ts
index be1686c49..a4ee7ca60 100644
--- a/src/app/authentication/services/auth.service.ts
+++ b/src/app/authentication/services/auth.service.ts
@@ -9,6 +9,7 @@ import { environment } from 'src/environments/environment';
 
 
 const AUTH_API = environment.smartharvesterUrl + '/harvester/auth';
+const FDP_URL = environment.fdpUrl;
 const httpOptions = {
   headers: new HttpHeaders({ 'Content-Type': 'application/json' })
 };
@@ -53,7 +54,7 @@ export class AuthService {
 
 
   getF2DSAuthToken(credentials): Observable<any> {
-    return this.http.post(this.appConfig.fdpurl + '/tokens', {
+    return this.http.post(FDP_URL + '/tokens', {
       email: credentials.email,
       password: credentials.password
     }, httpOptions);
diff --git a/src/app/dashboard/dashboard.component.ts b/src/app/dashboard/dashboard.component.ts
index 83fdcceab..2dab938b9 100644
--- a/src/app/dashboard/dashboard.component.ts
+++ b/src/app/dashboard/dashboard.component.ts
@@ -52,7 +52,7 @@ export class DashboardComponent implements OnInit {
       link: '/dashboard/simplesearch',
       pathMatch: 'full'
     },
-    {
+    /*{
       title: 'Settings',
       icon: 'options-2-outline',
       children: [
@@ -67,7 +67,7 @@ export class DashboardComponent implements OnInit {
           pathMatch: 'full'
         }
       ],
-    },
+    },*/
   ];
 
   constructor(private readonly sidebarService: NbSidebarService,
diff --git a/src/app/datasets/datasets.component.ts b/src/app/datasets/datasets.component.ts
index e823b558e..e57dc1e1b 100644
--- a/src/app/datasets/datasets.component.ts
+++ b/src/app/datasets/datasets.component.ts
@@ -4,6 +4,7 @@ import { DatasetCrudService } from './services/dataset-crud.service';
 import { OpenApi } from '../publishapi/class/openapi';
 import { ParameterType } from '../publishapi/class/openapi-enum';
 import { OpenApiTag } from '../publishapi/class/openapi-dto';
+import { environment } from 'src/environments/environment.prod';
 
 interface RequestInfo {
   value?: string;
@@ -26,6 +27,7 @@ export class DatasetsComponent implements OnInit {
   values = new Map<string, Map<string, Map<string, RequestInfo>>>();
   previews = new Map<string, any>();
   spinners = new Map<string, boolean>();
+  FDP_URL = environment.fdpUrl;
 
   
  
@@ -300,8 +302,8 @@ export class DatasetsComponent implements OnInit {
     data = '\@prefix dcat: <http://www.w3.org/ns/dcat#>.\n\
             @prefix dct: <http://purl.org/dc/terms/>.\n\
             @prefix language: <http://id.loc.gov/vocabulary/iso639-1/>.\n\
-            @prefix s: <'+ this.appConfig.fdpurl + '/>.\n\
-            @prefix c: <'+ this.appConfig.fdpurl + '/catalog/>.\n\
+            @prefix s: <'+ this.FDP_URL + '/>.\n\
+            @prefix c: <'+ this.FDP_URL+ '/catalog/>.\n\
     s:new\n\
       a dcat:Dataset, dcat:Resource;\n\
       dct:description ' + description + ';\n\
diff --git a/src/app/datasets/services/dataset-crud.service.ts b/src/app/datasets/services/dataset-crud.service.ts
index cafd63ee3..f894912d4 100644
--- a/src/app/datasets/services/dataset-crud.service.ts
+++ b/src/app/datasets/services/dataset-crud.service.ts
@@ -3,9 +3,10 @@ import { Injectable } from '@angular/core';
 import { Observable } from 'rxjs';
 import { AppConfiguration } from 'src/app/AppConfiguration';
 import { TokenStorageService } from 'src/app/authentication/services/token-storage.service';
+import { environment } from 'src/environments/environment.prod';
 import { ParseXmlService } from '../../services/parse-xml.service';
 
-
+const FDP_URL = environment.fdpUrl;
 @Injectable({
   providedIn: 'root'
 })
@@ -26,7 +27,7 @@ export class DatasetCrudService {
           })
         };
         
-        this.http.post(this.appConfig.fdpurl+"/dataset", data, httpOptions ).subscribe( r => {
+        this.http.post(FDP_URL +"/dataset", data, httpOptions ).subscribe( r => {
             console.log("resultat: " + JSON.stringify(r));
         },
         error => console.error("The repository has not been published: " + error) ,
@@ -50,7 +51,7 @@ export class DatasetCrudService {
         })
       };
       
-      let resultat = this.http.post(this.appConfig.fdpurl+"/distribution", data, httpOptions ).subscribe((r)=>{
+      let resultat = this.http.post(FDP_URL +"/distribution", data, httpOptions ).subscribe((r)=>{
         console.log('reponse: ', r);
         return JSON.stringify(resultat);
       }) ;
diff --git a/src/app/mapping/mapping.component.ts b/src/app/mapping/mapping.component.ts
index 27239c7d3..511a8a756 100644
--- a/src/app/mapping/mapping.component.ts
+++ b/src/app/mapping/mapping.component.ts
@@ -2,6 +2,7 @@
 import { Component, Input, OnInit, ViewChild } from '@angular/core';
 import { Observable, of } from 'rxjs';
 import { map } from 'rxjs/operators';
+import { environment } from 'src/environments/environment.prod';
 import { AppConfiguration } from '../AppConfiguration';
 import { DatasetCrudService } from '../datasets/services/dataset-crud.service';
 import { Dataset } from './class/Dataset';
@@ -26,6 +27,7 @@ export class MappingComponent implements OnInit {
   index: number = 0
   first: boolean = true;
   loading: boolean = false;
+  FDP_URL  = environment.fdpUrl;
   @ViewChild('autoInput') input;
   @Input() catalogId: any;
 
@@ -92,8 +94,8 @@ publishDataset() {
     data = '\@prefix dcat: <http://www.w3.org/ns/dcat#>.\n\
   @prefix dct: <http://purl.org/dc/terms/>.\n\
   @prefix language: <http://id.loc.gov/vocabulary/iso639-1/>.\n\
-  @prefix s: <'+ this.appConfig.fdpurl + '/>.\n\
-  @prefix c: <'+ this.appConfig.fdpurl + '/catalog/>.\n\
+  @prefix s: <'+ this.FDP_URL + '/>.\n\
+  @prefix c: <'+ this.FDP_URL + '/catalog/>.\n\
   \n\
 s:new\n\
 a dcat:Dataset, dcat:Resource;\n\
diff --git a/src/app/repository/repository.component.ts b/src/app/repository/repository.component.ts
index 00a7335ae..425df4800 100644
--- a/src/app/repository/repository.component.ts
+++ b/src/app/repository/repository.component.ts
@@ -22,6 +22,7 @@ export class RepositoryComponent implements OnInit {
   public importFile: File;
   public resultat: any;
   public persistentUrl: string;
+  FDP_URL = environment.fdpUrl;
 
   Form = new FormGroup({
     repotype: new FormControl(),
@@ -115,7 +116,7 @@ repository:\n\
 @prefix dct: <http://purl.org/dc/terms/>.\n\
 @prefix foaf:  <http://xmlns.com/foaf/0.1/> .\n\
 @prefix lang: <http://id.loc.gov/vocabulary/iso639-1/>. \n\
-@prefix fdp: <'+ this.appConfig.fdpurl + '/>.\n\nfdp:new \n\
+@prefix fdp: <'+ this.FDP_URL + '/>.\n\nfdp:new \n\
     a dcat:Catalog, dcat:Resource;\n\
     dct:description "'+ this.Form.value.repodescription + '";\n\
     dct:hasVersion "'+ this.Form.value.repoversion + '";\n\
diff --git a/src/app/repository/services/publish-repository.service.ts b/src/app/repository/services/publish-repository.service.ts
index 913909bbc..934455262 100644
--- a/src/app/repository/services/publish-repository.service.ts
+++ b/src/app/repository/services/publish-repository.service.ts
@@ -10,7 +10,7 @@ interface PersistentUrlResponse {
   persistentUrl: string;
 }
 
-
+const FDP_URL = environment.fdpUrl;
 @Injectable({
   providedIn: 'root'
 })
@@ -38,7 +38,7 @@ export class PublishRepositoryService {
         myHeaders.append('Authorization', 'Bearer ' + this.fds2Token);
         const myInit = { method: 'POST', body: data, headers: myHeaders };
 
-        const myRequest = new Request(this.appConfig.fdpurl + "/catalog", myInit);
+        const myRequest = new Request(FDP_URL + "/catalog", myInit);
 
         fetch(myRequest, myInit)
           .then(response => {
diff --git a/src/app/services/catalog.service.ts b/src/app/services/catalog.service.ts
index e90209f39..f839c4026 100644
--- a/src/app/services/catalog.service.ts
+++ b/src/app/services/catalog.service.ts
@@ -17,6 +17,8 @@ export interface FdpApiResponseItem {
   context: string
 }
 
+const FDP_URL = environment.fdpUrl;
+
 @Injectable({
   providedIn: 'root'
 })
@@ -49,6 +51,6 @@ export class CatalogService {
   }
 
   getCatalogContentById(catId: string) {
-    return this.http.get<FdpApiResponseItem[]>(this.appConfig.fdpurl + '/catalog/' + catId, this.httpOptionsFDP);
+    return this.http.get<FdpApiResponseItem[]>(FDP_URL + '/catalog/' + catId, this.httpOptionsFDP);
   }
 }
-- 
GitLab


From 91adbfb57422bdaef6429110c1ea7eb590ac8d79 Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Fri, 16 Jul 2021 10:18:42 +0200
Subject: [PATCH 17/18] remove step 4

---
 src/app/publishapi/publishapi.component.html | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/app/publishapi/publishapi.component.html b/src/app/publishapi/publishapi.component.html
index 693ef4e73..1640975f8 100644
--- a/src/app/publishapi/publishapi.component.html
+++ b/src/app/publishapi/publishapi.component.html
@@ -302,9 +302,9 @@
         </p> 
           <app-mapping *ngIf="initLabelThree" [catalogId]="openApi.info['x-catalog-id']"></app-mapping>
         <button class="prev-button" nbButton nbStepperPrevious (click)="initLabelThree = false">prev</button>
-        <button class="next-button" nbButton nbStepperNext>next</button>
+        <button class="next-button" nbButton disabled nbStepperNext>next</button>
       </nb-step>
-      <nb-step [label]="labelFour">
+      <!--<nb-step [label]="labelFour">
         <ng-template #labelFour>Fourth step</ng-template>
         <h4>Populate FDP</h4>
         <p class="lorem">
@@ -312,7 +312,7 @@
         </p>
         <button class="prev-button" nbButton nbStepperPrevious>prev</button>
         <button class="next-button" nbButton disabled nbStepperNext>next</button>
-      </nb-step>
+      </nb-step>-->
     </nb-stepper>
   </nb-card-body>
 </nb-card>
-- 
GitLab


From d5d134c7daab520f18dfedebf5060dc82f448b1c Mon Sep 17 00:00:00 2001
From: Baptiste Toulemonde <toulemonde@cines.fr>
Date: Fri, 16 Jul 2021 13:50:05 +0200
Subject: [PATCH 18/18] mapping: delete dataset

---
 src/app/mapping/mapping.component.html | 40 ++++++++++++++------------
 src/app/mapping/mapping.component.scss |  7 ++++-
 src/app/mapping/mapping.component.ts   |  7 +++--
 3 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/src/app/mapping/mapping.component.html b/src/app/mapping/mapping.component.html
index 0ad1f4190..cd2e7483b 100644
--- a/src/app/mapping/mapping.component.html
+++ b/src/app/mapping/mapping.component.html
@@ -1,9 +1,7 @@
 <div class="card-row">
     <div class="card-col">
-        <nb-card size="giant" [nbSpinner]="loading"
-        nbSpinnerStatus="primary"
-             nbSpinnerSize="large"
-             nbSpinnerMessage="Loading...">
+        <nb-card size="giant" [nbSpinner]="loading" nbSpinnerStatus="primary" nbSpinnerSize="large"
+            nbSpinnerMessage="Loading...">
             <nb-card-header>Dataset metadata</nb-card-header>
             <nb-card-body>
                 <div></div>
@@ -53,31 +51,35 @@
 </div>
 <div class="card-row">
     <div class="card-col">
-        <nb-card >
+        <nb-card>
             <nb-card-header>Map</nb-card-header>
             <nb-card-body>
                 <nb-list>
-                    
-                        <nb-list-item *ngFor="let data of mappedMetadatas[index] | keyvalue ">
-                            <div class="row">
-                                <div class="col-5">{{data.key}} : </div>
-                                <div class="col-5">{{data.value}}</div>
-                                <div class="col-2"><button nbButton ghost>
-                                        <nb-icon icon="trash-2-outline" status="danger" (click)="deleteProperty(data.key)">
-                                        </nb-icon>
-                                    </button></div>
-                            </div>
-                        </nb-list-item>
-                    
-                </nb-list>
 
+                    <nb-list-item *ngFor="let data of mappedMetadatas[index] | keyvalue; trackBy:trackByIndex; ">
+                        <div class="row">
+                            <div class="col-5"><label for="{{data.key}}">{{data.key}}</label></div>
+                            <div class="col-5"> <input nbInput autofocus [ngModel]="data.value"
+                                    (ngModelChange)="mappedMetadatas[index].set(data.key, $event)" /> </div>
+                            <div class="col-2"><button nbButton ghost>
+                                    <nb-icon icon="trash-2-outline" status="danger" (click)="deleteProperty(data.key)">
+                                    </nb-icon>
+                                </button></div>
+                        </div>
+                    </nb-list-item>
+
+                </nb-list>
+                <div class="row">
+                    <button class="button-center" nbButton status="danger" (click)="mappedMetadatas.splice(index, 1); prev()">Delete datset<nb-icon icon="trash-2-outline">
+                        </nb-icon></button>
+                </div>
             </nb-card-body>
             <nb-card-footer>
                 <div class="row">
                     <div *ngIf=" !first ">
                         <button nbButton (click)=" prev()" [disabled]="index == 0">prev</button>
                     </div>
-                    
+
                     <div *ngIf="!first ">
                         <button nbButton (click)=" next()" [disabled]="index == mappedMetadatas.length -1">next</button>
                     </div>
diff --git a/src/app/mapping/mapping.component.scss b/src/app/mapping/mapping.component.scss
index 4c11d8514..9a0e26439 100644
--- a/src/app/mapping/mapping.component.scss
+++ b/src/app/mapping/mapping.component.scss
@@ -18,7 +18,7 @@
 
   .col-5 {
     width: 45%;
-    
+    vertical-align: middle;
     margin-right: 10px;
     align-items: stretch;
   }
@@ -48,4 +48,9 @@
 
   input-basic-disabled-text-color {
     color: black;
+  }
+
+  .button-center{
+    vertical-align: middle;
+    margin: auto
   }
\ No newline at end of file
diff --git a/src/app/mapping/mapping.component.ts b/src/app/mapping/mapping.component.ts
index 511a8a756..3d3c947af 100644
--- a/src/app/mapping/mapping.component.ts
+++ b/src/app/mapping/mapping.component.ts
@@ -102,7 +102,7 @@ a dcat:Dataset, dcat:Resource;\n\
 dct:isPartOf c:'+ this.catalogId + ';\n' + properties + '.';
 
   console.log('data: ' + data);
-  this.dataSetService.createDataSet(data);
+  //this.dataSetService.createDataSet(data);
   })
   
 }
@@ -145,7 +145,10 @@ dct:isPartOf c:'+ this.catalogId + ';\n' + properties + '.';
     }
   }
   prev() {
-    this.index -= 1;
+    if(this.index > 0){
+      this.index -= 1;
+    }
+    
     this.createDataset(this.itemsdataset[this.index])
     console.log('index = ' + this.index);
   }
-- 
GitLab