Commit eae62ae7 authored by Célia Michotey's avatar Célia Michotey
Browse files

Add About, Help, How to join and Legal mentions links in FAIDARE navbar. GNP-5519.

parent 222522d8
# About this application
# Help section
# How to join FAIDARE federation?
# General Terms of Use
By browsing this web site, you acknowledge and accept its general terms of use described below.
## Intellectual property
Except where otherwise noted, content on this site is licensed under a [Creative Commons Attribution 4.0 International license](https://creativecommons.org/licenses/by/4.0/).
The logo is the property of INRA and you are not allowed to re-use it for your own work and purpose.
## Content
The portal maintained by INRA allows to find public data across a federation of databases.
The licences associated to data are therefore defined by the institutes in charge of them.
Users are sole responsible for the searches they carry out, as well as for the interpretation and for the use they make of the results.
The access to the web site can be interrupted at any moment and without prior warning in case of force majeure or if the editor decides to terminate its provision of service.
Users are informed that their use of the results should not infringe on current legislation or the recommendations of the French Data Protection Authority (CNIL) with respect to personal data.
Users are warned that the information must be used for strictly professional purposes only and downloading screen shots in order to constitute or enrich a database is contrary to French law and therefore forbidden, as is its use for commercial or advertising purposes (CNIL).
The portal may give access to personal and professional data concerning technical and scientific actors in relation with the data.
This information helps to identify and acknowledge the authors of the scientific works.
This personal information is attached to the produced datasets and follows the data life cycle.
## Hyperlinks
The portal links to external web sites.
INRA does not take responsibility of the content of these web site.
## Personal data
Technical data (date, hour, IP address of the computer of the visitor, pages viewed) are collected only for the statistical analysis of the usage of the portal.
These data are kept confidential and not transmitted to any other party.
They are stored on INRA’s private servers for 5 years.
During visits on URGI web site and its hosted applications, a cookie can be automatically installed on visitor’s web browsers to retrieve statistics on the pages that are visited and support improvements of the services provided by the web site.
Visitors can configure their web browsers in order to be informed of the setting of cookies and refuse them.
According to the European Regulation on the protection of personal data (EU Regulation 2016/679), you have the right to access, rectify, oppose and delete information about yourself.
If you wish to exercise this right and obtain information about yourself, please contact us:
- By [email](mailto:urgi-contact@inra.fr?subject=%5BData%20Discovery%5D%20GPDR%20request)
- Or via any other way available on our [contact form](https://urgi.versailles.inra.fr/Contact-us)
## Modifications
The editor might change the terms of use and user’s rights without prior warning.
Last update: 2019 June 25th
package fr.inra.urgi.faidare.config;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.MimeMappings;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;
/**
* MimeMappings configuration. Ensure that markdown files are correctly returned with the good MimeType
* @author R. Flores
*/
@Configuration
public class MimeMappingServletCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory factory) {
MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
mappings.add("md", "text/markdown");
factory.setMimeMappings(mappings);
}
}
......@@ -75,6 +75,7 @@ server:
- application/javascript
- text/html
- text/css
- text/markdown
port: 8380
servlet:
context-path: /faidare-dev
......
......@@ -857,6 +857,11 @@
"@types/leaflet": "*"
}
},
"@types/marked": {
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.6.5.tgz",
"integrity": "sha512-6kBKf64aVfx93UJrcyEZ+OBM5nGv4RLsI6sR1Ar34bpgvGVRoyTgpxn4ZmtxOM5aDTAaaznYuYUH8bUX3Nk3YA=="
},
"@types/node": {
"version": "8.9.5",
"resolved": "http://registry.npmjs.org/@types/node/-/node-8.9.5.tgz",
......@@ -2227,6 +2232,17 @@
"integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
"dev": true
},
"clipboard": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz",
"integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==",
"optional": true,
"requires": {
"good-listener": "^1.2.2",
"select": "^1.1.2",
"tiny-emitter": "^2.0.0"
}
},
"cliui": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
......@@ -2860,6 +2876,12 @@
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"dev": true
},
"delegate": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
"optional": true
},
"delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
......@@ -4484,6 +4506,15 @@
"minimatch": "~3.0.2"
}
},
"good-listener": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
"optional": true,
"requires": {
"delegate": "^3.1.2"
}
},
"graceful-fs": {
"version": "4.1.15",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
......@@ -6235,6 +6266,11 @@
"object-visit": "^1.0.0"
}
},
"marked": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.6.2.tgz",
"integrity": "sha512-LqxwVH3P/rqKX4EKGz7+c2G9r98WeM/SW34ybhgNGhUQNKtf1GmmSkJ6cDGJ/t6tiyae49qRkpyTw2B9HOrgUA=="
},
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
......@@ -6592,6 +6628,17 @@
"resolved": "https://registry.npmjs.org/ng-mocks/-/ng-mocks-7.6.0.tgz",
"integrity": "sha512-Zorpd5I6KmvTtiYwcjymzCaortznMZr5CRB737XaNheITTUb2rVLUoEBk1dwQE3b/Cp5sByuS85fzwJRvjEXKQ=="
},
"ngx-markdown": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/ngx-markdown/-/ngx-markdown-8.0.2.tgz",
"integrity": "sha512-dLF205/JrSI7pOIgsrikhf9KYF6yiP797FuHGjVEw51KhHfuhCoR+3pl7Ky2vxuQBJjmkNGbgH75+Qy2SAnFEg==",
"requires": {
"@types/marked": "^0.6.0",
"marked": "^0.6.0",
"prismjs": "^1.16.0",
"tslib": "^1.9.0"
}
},
"ngx-moment": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/ngx-moment/-/ngx-moment-3.3.0.tgz",
......@@ -7531,6 +7578,14 @@
"integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
"dev": true
},
"prismjs": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.16.0.tgz",
"integrity": "sha512-OA4MKxjFZHSvZcisLGe14THYsug/nF6O1f0pAJc0KN0wTyAcLqmsbE+lTGKSpyh+9pEW57+k6pg2AfYR+coyHA==",
"requires": {
"clipboard": "^2.0.0"
}
},
"process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
......@@ -8321,6 +8376,12 @@
}
}
},
"select": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
"optional": true
},
"select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
......@@ -9526,6 +9587,12 @@
"setimmediate": "^1.0.4"
}
},
"tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
"optional": true
},
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
......
......@@ -33,6 +33,7 @@
"leaflet.markercluster": "1.4.1",
"moment": "2.24.0",
"ng-mocks": "^7.6.0",
"ngx-markdown": "^8.0.2",
"ngx-moment": "3.3.0",
"popper.js": "1.14.6",
"rxjs": "6.4.0",
......
......@@ -4,12 +4,19 @@ import { ResultPageComponent } from './result-page/result-page.component';
import { GermplasmCardComponent } from './germplasm-card/germplasm-card.component';
import { StudyCardComponent } from './study-card/study-card.component';
import { SiteCardComponent } from './site-card/site-card.component';
import { MarkdownPageComponent } from "./markdown-page/markdown-page.component";
import { environment } from "../environments/environment";
export const routes: Routes = [
{ path: 'studies/:id', component: StudyCardComponent },
{ path: 'sites/:id', component: SiteCardComponent },
{ path: '', component: ResultPageComponent },
{ path: 'germplasm', component: GermplasmCardComponent }
{ path: 'germplasm', component: GermplasmCardComponent },
{ path: 'about', component: MarkdownPageComponent, data: { mdFile: environment.aboutUsMdFile } },
{ path: 'join', component: MarkdownPageComponent, data: { mdFile: environment.joinUsMdFile } },
{ path: 'legal', component: MarkdownPageComponent, data: { mdFile: environment.legalMentionsMdFile } },
{ path: 'help', component: MarkdownPageComponent, data: { mdFile: environment.helpMdFile } },
];
@NgModule({
......
......@@ -7,7 +7,7 @@ import { ResultPageComponent } from './result-page/result-page.component';
import { GermplasmCardComponent } from './germplasm-card/germplasm-card.component';
import { StudyCardComponent } from './study-card/study-card.component';
import { SiteCardComponent } from './site-card/site-card.component';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { HTTP_INTERCEPTORS, HttpClient, HttpClientModule } from '@angular/common/http';
import { NavbarComponent } from './navbar/navbar.component';
import { MapComponent } from './map/map.component';
import { NgbAlertModule, NgbDropdownModule, NgbPaginationModule, NgbPopoverModule, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
......@@ -26,7 +26,8 @@ import { MomentModule } from 'ngx-moment';
import { XrefsComponent } from './xrefs/xrefs.component';
import { CoordinatesModule } from 'angular-coordinates';
import { CardGenericDocumentComponent } from './card-generic-document/card-generic-document.component';
import { MarkdownModule, MarkedOptions, MarkedRenderer } from "ngx-markdown";
import { MarkdownPageComponent } from "./markdown-page/markdown-page.component";
@NgModule({
declarations: [
......@@ -48,7 +49,8 @@ import { CardGenericDocumentComponent } from './card-generic-document/card-gener
LoadingSpinnerComponent,
CardTableComponent,
XrefsComponent,
CardGenericDocumentComponent
CardGenericDocumentComponent,
MarkdownPageComponent
],
imports: [
BrowserModule,
......@@ -62,7 +64,24 @@ import { CardGenericDocumentComponent } from './card-generic-document/card-gener
FormsModule,
ReactiveFormsModule,
MomentModule,
CoordinatesModule
CoordinatesModule,
MarkdownModule.forRoot({
loader: HttpClient, // optional, only if you use [src] attribute
markedOptions: {
provide: MarkedOptions,
useFactory: markedOptionsFactory,
useValue: {
gfm: true, // default
tables: true,
breaks: false,
pedantic: false,
sanitize: false,
smartLists: true,
smartypants: false
},
}
}),
],
providers: [
{ provide: HTTP_INTERCEPTORS, useExisting: ErrorInterceptorService, multi: true }
......@@ -71,3 +90,19 @@ import { CardGenericDocumentComponent } from './card-generic-document/card-gener
})
export class AppModule {
}
export function markedOptionsFactory(): MarkedOptions {
const renderer = new MarkedRenderer();
renderer.link = (href: string, title: string, text: string) => {
if (href.startsWith('#')) {
const fragment = href.split('#')[1];
return `<a href='${location.pathname}#${fragment}'>${text}</a>`;
}
return `<a href="${href}" target="_blank" >${text}</a>`;
};
return {
renderer: renderer
};
}
<markdown [src]="mdFile" lineNumbers="true" (error)="onError($event)"
(load)="onLoad($event)"></markdown>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { MarkdownPageComponent } from './markdown-page.component';
import { ActivatedRoute } from "@angular/router";
import { environment } from "../../environments/environment";
import { of } from "rxjs";
describe('MarkdownPageComponent', () => {
let component: MarkdownPageComponent;
let fixture: ComponentFixture<MarkdownPageComponent>;
const route = ({ data: of({ mdFile: environment.helpMdFile }) } as any) as ActivatedRoute;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MarkdownPageComponent ],
providers: [{ provide: ActivatedRoute, useValue: route }],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MarkdownPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
expect(component.mdFile).toEqual('assets/help.md');
});
});
import { Component, OnInit } from '@angular/core';
import {ActivatedRoute} from "@angular/router";
@Component({
selector: 'dd-about',
templateUrl: './markdown-page.component.html',
styleUrls: ['./markdown-page.component.scss']
})
export class MarkdownPageComponent implements OnInit {
mdFile: string = "";
constructor(private route: ActivatedRoute) {
}
ngOnInit() {
this.route.data.subscribe(
value => this.mdFile = value.mdFile);
}
onLoad(e: any) {
// console.log('Into onLoad');
// console.log(e);
}
onError(e: any) {
console.log('Got error', e);
}
}
......@@ -18,25 +18,40 @@
<!-- OR Dropdown button -->
<div class="mr-2" *ngIf="link.subMenu" class="dropdown-container" ngbDropdown>
<!-- Toggle button -->
<a class="nav-link d-flex align-items-center dropdown-toggle" ngbDropdownToggle
role="button"
aria-haspopup="true"
aria-expanded="false">
{{ link.label }}
</a>
aria-expanded="false">{{ link.label }}</a>
<!-- Items -->
<div class="dropdown-menu" ngbDropdownMenu>
<div *ngFor="let subItem of link.subMenu">
<a class="dropdown-item"
target="_blank"
[href]="subItem.url">
{{ subItem.label }}
</a>
target="_blank" [href]="subItem.url">{{ subItem.label }}</a>
</div>
</div>
</div>
</li>
<!-- Documentation -->
<li class="nav-item">
<div class="mr-2" class="dropdown-container" ngbDropdown>
<a class="nav-link d-flex align-items-center dropdown-toggle" ngbDropdownToggle
role="button"
aria-haspopup="true"
aria-expanded="false">
More ...
</a>
<div class="dropdown-menu" ngbDropdownMenu>
<!-- About link -->
<a class="dropdown-item" routerLink="/about" routerLinkActive="true" title="About">About</a>
<!-- Join us link -->
<a class="dropdown-item" routerLink="/join" routerLinkActive="true" title="Join us">Join us</a>
<!-- Legal mentions link -->
<a class="dropdown-item" routerLink="/legal" routerLinkActive="true" title="Legal mentions" >Legal mentions</a>
<!-- Help link -->
<a class="dropdown-item" routerLink="/help" routerLinkActive="true" title="Help">Help</a>
</div>
</div>
</li>
</ul>
......
import { async, TestBed } from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NavbarComponent } from './navbar.component';
import { ComponentTester } from 'ngx-speculoos';
......@@ -20,7 +20,15 @@ class NavbarComponentTester extends ComponentTester<NavbarComponent> {
}
get links() {
return this.elements('li a');
return this.elements('li');
}
get firstLink() {
return this.element('li').element('a');
}
get firstLinkSubLinks() {
return this.element('li').elements('a');
}
get logo() {
......@@ -30,42 +38,9 @@ class NavbarComponentTester extends ComponentTester<NavbarComponent> {
describe('NavbarComponent', () => {
const dataSource1: DataDiscoverySource = {
'@id': 'urn:source1',
'@type': ['schema:DataCatalog'],
'schema:name': 'Example source1',
'schema:url': 'http://example1.com',
'schema:image': 'http://example1.com/logo.png'
};
const dataSource2: DataDiscoverySource = {
'@id': 'urn:source2',
'@type': ['schema:DataCatalog'],
'schema:name': 'Example source2',
'schema:url': 'http://example2.com',
'schema:image': 'http://example2.com/logo.png'
};
let gnpisService;
beforeEach(() => {
gnpisService = jasmine.createSpyObj(
'GnpisService', [
'getSource',
'suggest'
]
);
gnpisService.suggest.and.returnValue(of([dataSource1['@id'], dataSource2['@id']]));
gnpisService.getSource.withArgs(dataSource1['@id']).and.returnValue(of(dataSource1));
gnpisService.getSource.withArgs(dataSource2['@id']).and.returnValue(of(dataSource2));
TestBed.configureTestingModule({
declarations: [NavbarComponent],
providers: [
{ provide: GnpisService, useValue: gnpisService }
]
}).compileComponents();
});
beforeEach(() => TestBed.configureTestingModule({
declarations: [NavbarComponent]
}));
it('should toggle the class on click', () => {
const tester = new NavbarComponentTester();
......@@ -90,8 +65,14 @@ describe('NavbarComponent', () => {
title: 'FAIR Data-finder for Agronomic REsearch',
logo: 'assets/applicationLogo.png',
links: [
{ label: 'INRA', url: 'http://www.inra.fr/' },
{
label: 'Data providers',
url: '#',
subMenu: [
{ label: 'GNPIS', url: 'https://urgi.versailles.inra.fr/gnpis/' },
{ label: 'URGI', url: 'https://urgi.versailles.inra.fr/' }
]
}
],
contributor: {
name: 'Elixir',
......@@ -106,12 +87,17 @@ describe('NavbarComponent', () => {
expect(tester.logo.attr('title')).toBe('FAIR Data-finder for Agronomic REsearch');
expect(tester.links.length - 1).toBe(1);
// minus 1 because of More section (containing Help, About, Join and Legal links) added automatically
// Two static links + two dynamic links (fetched data sources)
expect(tester.links.length).toBe(4);
//expect(tester.links.length).toBe(4);
expect(tester.links[0].textContent).toBe('INRA');
expect(tester.links[0].attr('href')).toBe('http://www.inra.fr/');
expect(tester.links[0].attr('target')).toBe('_blank');
}));
})
;
expect(tester.firstLink.textContent).toBe('Data providers');
expect(tester.firstLinkSubLinks.length -1).toBe(2);
// minus 1 because of the dropdown link
expect(tester.firstLinkSubLinks.pop().attr('href')).toBe('https://urgi.versailles.inra.fr/');
expect(tester.firstLinkSubLinks.pop().textContent).toBe('URGI');
expect(tester.firstLinkSubLinks.pop().attr('target')).toBe('_blank');
});
});
../../../../ABOUT.md
\ No newline at end of file
../../../../HELP.md
\ No newline at end of file
../../../../HOW-TO-JOIN.md
\ No newline at end of file
../../../../LEGAL-MENTIONS.md
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment