From 1031a3ae4bd1f0bd260a63d464135b1125c44f80 Mon Sep 17 00:00:00 2001 From: gcornut <guillaume.cornut@inra.fr> Date: Thu, 21 Feb 2019 16:56:25 +0100 Subject: [PATCH 1/6] fix: Use font awesome spinner everywhere. #5 --- ...STS-HeadlessChrome_0.0.0_(Linux_0.0.0).xml | 0 .../germplasm-card.component.html | 2 +- .../loading-spinner.component.html | 15 --- .../loading-spinner.component.scss | 96 ------------------- .../loading-spinner.component.spec.ts | 25 ----- .../loading-spinner.component.ts | 20 ++-- .../result-page/result-page.component.html | 17 +--- .../app/site-card/site-card.component.html | 2 +- .../app/study-card/study-card.component.html | 2 +- frontend/src/assets/gpds/theme.scss | 12 --- frontend/src/styles.scss | 7 -- 11 files changed, 16 insertions(+), 182 deletions(-) delete mode 100644 frontend/karma-junit-tests-report/TESTS-HeadlessChrome_0.0.0_(Linux_0.0.0).xml delete mode 100644 frontend/src/app/loading-spinner/loading-spinner.component.html delete mode 100644 frontend/src/app/loading-spinner/loading-spinner.component.scss delete mode 100644 frontend/src/app/loading-spinner/loading-spinner.component.spec.ts diff --git a/frontend/karma-junit-tests-report/TESTS-HeadlessChrome_0.0.0_(Linux_0.0.0).xml b/frontend/karma-junit-tests-report/TESTS-HeadlessChrome_0.0.0_(Linux_0.0.0).xml deleted file mode 100644 index e69de29b..00000000 diff --git a/frontend/src/app/germplasm-card/germplasm-card.component.html b/frontend/src/app/germplasm-card/germplasm-card.component.html index 5fa9f5eb..80c26df8 100644 --- a/frontend/src/app/germplasm-card/germplasm-card.component.html +++ b/frontend/src/app/germplasm-card/germplasm-card.component.html @@ -1,4 +1,4 @@ -<gpds-loading-spinner [loading]="loading" class="display-spinner-front rounded"></gpds-loading-spinner> +<gpds-loading-spinner [loading]="loading" class="float-right"></gpds-loading-spinner> <ng-container *ngIf="germplasmGnpis"> <h3> diff --git a/frontend/src/app/loading-spinner/loading-spinner.component.html b/frontend/src/app/loading-spinner/loading-spinner.component.html deleted file mode 100644 index 01060a7d..00000000 --- a/frontend/src/app/loading-spinner/loading-spinner.component.html +++ /dev/null @@ -1,15 +0,0 @@ -<!-- Loading (see CSS for animation)--> -<div *ngIf="loading" class="lds-spinner mx-auto"> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> -</div> diff --git a/frontend/src/app/loading-spinner/loading-spinner.component.scss b/frontend/src/app/loading-spinner/loading-spinner.component.scss deleted file mode 100644 index 3c571d09..00000000 --- a/frontend/src/app/loading-spinner/loading-spinner.component.scss +++ /dev/null @@ -1,96 +0,0 @@ -// Loading spinner -.lds-spinner { - $scale: 1.2; - - color: black; - display: block; - position: relative; - width: 64px * $scale; - height: 64px * $scale; - - div { - transform-origin: 32px * $scale 32px * $scale; - animation: lds-spinner 1.2s linear infinite; - } - - div:after { - content: " "; - display: block; - position: absolute; - top: 3px; - left: 29px * $scale; - width: 5px * $scale; - height: 14px * $scale; - border-radius: 20%; - background: black; - } - - div:nth-child(1) { - transform: rotate(0deg); - animation-delay: -1.1s; - } - - div:nth-child(2) { - transform: rotate(30deg); - animation-delay: -1s; - } - - div:nth-child(3) { - transform: rotate(60deg); - animation-delay: -0.9s; - } - - div:nth-child(4) { - transform: rotate(90deg); - animation-delay: -0.8s; - } - - div:nth-child(5) { - transform: rotate(120deg); - animation-delay: -0.7s; - } - - div:nth-child(6) { - transform: rotate(150deg); - animation-delay: -0.6s; - } - - div:nth-child(7) { - transform: rotate(180deg); - animation-delay: -0.5s; - } - - div:nth-child(8) { - transform: rotate(210deg); - animation-delay: -0.4s; - } - - div:nth-child(9) { - transform: rotate(240deg); - animation-delay: -0.3s; - } - - div:nth-child(10) { - transform: rotate(270deg); - animation-delay: -0.2s; - } - - div:nth-child(11) { - transform: rotate(300deg); - animation-delay: -0.1s; - } - - div:nth-child(12) { - transform: rotate(330deg); - animation-delay: 0s; - } -} - -@keyframes lds-spinner { - 0% { - opacity: 1; - } - 100% { - opacity: 0; - } -} diff --git a/frontend/src/app/loading-spinner/loading-spinner.component.spec.ts b/frontend/src/app/loading-spinner/loading-spinner.component.spec.ts deleted file mode 100644 index 88109e14..00000000 --- a/frontend/src/app/loading-spinner/loading-spinner.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { LoadingSpinnerComponent } from './loading-spinner.component'; - -describe('LoadingSpinnerComponent', () => { - let component: LoadingSpinnerComponent; - let fixture: ComponentFixture<LoadingSpinnerComponent>; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [LoadingSpinnerComponent] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(LoadingSpinnerComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/frontend/src/app/loading-spinner/loading-spinner.component.ts b/frontend/src/app/loading-spinner/loading-spinner.component.ts index 24cb5902..62e34fb2 100644 --- a/frontend/src/app/loading-spinner/loading-spinner.component.ts +++ b/frontend/src/app/loading-spinner/loading-spinner.component.ts @@ -1,18 +1,18 @@ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, Input } from '@angular/core'; @Component({ selector: 'gpds-loading-spinner', - templateUrl: './loading-spinner.component.html', - styleUrls: ['./loading-spinner.component.scss'] + template: ` + <i *ngIf="loading" class="fa fa-spin fa-spinner" title="Loading..."></i> + `, + styles: [` + i { + font-size: 2.2em; + } + `] }) -export class LoadingSpinnerComponent implements OnInit { +export class LoadingSpinnerComponent { @Input() loading: boolean; - constructor() { - } - - ngOnInit() { - } - } diff --git a/frontend/src/app/result-page/result-page.component.html b/frontend/src/app/result-page/result-page.component.html index e846e026..b8bd5aad 100644 --- a/frontend/src/app/result-page/result-page.component.html +++ b/frontend/src/app/result-page/result-page.component.html @@ -31,20 +31,9 @@ <!-- Column for result --> <div class="col-lg-9"> - <!-- Loading (see CSS for animation)--> - <div *ngIf="loading" class="lds-spinner mx-auto" > - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> - <div></div> + <!-- Loading spinner--> + <div class="text-center"> + <gpds-loading-spinner [loading]="loading"></gpds-loading-spinner> </div> <!-- No criteria selected --> diff --git a/frontend/src/app/site-card/site-card.component.html b/frontend/src/app/site-card/site-card.component.html index f30867c6..2bfeb13c 100644 --- a/frontend/src/app/site-card/site-card.component.html +++ b/frontend/src/app/site-card/site-card.component.html @@ -1,4 +1,4 @@ -<gpds-loading-spinner [loading]="loading"></gpds-loading-spinner> +<gpds-loading-spinner [loading]="loading" class="float-right"></gpds-loading-spinner> <ng-container *ngIf="location"> <h3> diff --git a/frontend/src/app/study-card/study-card.component.html b/frontend/src/app/study-card/study-card.component.html index c010cf49..f12d1173 100644 --- a/frontend/src/app/study-card/study-card.component.html +++ b/frontend/src/app/study-card/study-card.component.html @@ -1,4 +1,4 @@ -<gpds-loading-spinner class="display-spinner-front rounded" [loading]="loading"></gpds-loading-spinner> +<gpds-loading-spinner [loading]="loading" class="float-right"></gpds-loading-spinner> <ng-container *ngIf="study"> <h3> diff --git a/frontend/src/assets/gpds/theme.scss b/frontend/src/assets/gpds/theme.scss index ad6939cc..286d878c 100644 --- a/frontend/src/assets/gpds/theme.scss +++ b/frontend/src/assets/gpds/theme.scss @@ -71,18 +71,6 @@ h4 { text-overflow: ellipsis; } -.field { - -} - -.fieldName { - -} - -.headerTitle { - -} - // custom button $theme-btn-color: $white; $theme-btn-bg-color: $_theme-black; diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss index 2af3b3a2..b7abb8b9 100644 --- a/frontend/src/styles.scss +++ b/frontend/src/styles.scss @@ -13,10 +13,3 @@ $fa-font-path: '~font-awesome/fonts'; a { text-decoration: underline; } - -.display-spinner-front { - position: absolute; - top: 70px; - left: 720px; - background-color: #F9F9F9; -} -- GitLab From 12abccb99e7c24c56c7853e821ec7f74cbd65b71 Mon Sep 17 00:00:00 2001 From: gcornut <guillaume.cornut@inra.fr> Date: Thu, 21 Feb 2019 16:56:55 +0100 Subject: [PATCH 2/6] fix: Minor map component fixes. #5 --- frontend/src/app/map/map.component.ts | 36 +++++++++++++++------------ 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/frontend/src/app/map/map.component.ts b/frontend/src/app/map/map.component.ts index 23d72dcb..df746dd8 100644 --- a/frontend/src/app/map/map.component.ts +++ b/frontend/src/app/map/map.component.ts @@ -16,33 +16,37 @@ export class MapComponent implements OnInit { } ngOnInit() { - // initialize map centered on the first site - const firstLocation: BrapiLocation = this.locations[0]; const container = L.DomUtil.get('map'); if (container) { - const map = L.map('map').setView([firstLocation.latitude, firstLocation.longitude], 5); + const map = L.map('map'); + + // initialize map centered on the first site + const firstLocation: BrapiLocation = this.locations[0]; + if (firstLocation) { + map.setView([firstLocation.latitude, firstLocation.longitude], 5); + } + L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', { attribution: 'Tiles © Esri — Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, ' + 'Esri China (Hong Kong), Esri (Thailand), TomTom, 2012' }).addTo(map); // add markers for all locations using markercluster plugin const markers = new MarkerClusterGroup(); - for (const site of this.locations) { + for (const location of this.locations) { const icon = L.icon({ - iconUrl: this.getMarkerIconUrl(site) + iconUrl: this.getMarkerIconUrl(location) }); - let iconText: string = '<b>' + site.locationName + '</b><br/>'; - iconText += site.locationType + '<br/>'; - iconText += `<a href="sites/${site.locationDbId}">Details</a>`; - markers.addLayer(L.marker( - [site.latitude, site.longitude], - { icon: icon } - ).bindPopup(iconText) + const popupText = ` + <b>${location.locationName}</b><br/> + ${location.locationType}<br/> + <a href="sites/${location.locationDbId}">Details</a> + `; + markers.addLayer( + L.marker( + [location.latitude, location.longitude], + { icon: icon } + ).bindPopup(popupText) ); - /* L.marker( - [site.result.latitude, site.result.longitude], - { icon: icon } - ).bindPopup(iconText).addTo(map); */ } map.addLayer(markers); } -- GitLab From a0c736619936cd98d71a88a724e8e1ba2e1b3d47 Mon Sep 17 00:00:00 2001 From: gcornut <guillaume.cornut@inra.fr> Date: Thu, 21 Feb 2019 18:25:11 +0100 Subject: [PATCH 3/6] fix: Fix loading spinner still displaying after an error occurred. Add back to previous page button in error message. --- frontend/src/app/error/error.component.html | 27 +++++++++++-------- .../src/app/error/error.component.spec.ts | 4 ++- frontend/src/app/error/error.component.ts | 16 ++++++++--- .../loading-spinner.component.ts | 14 ++++++++-- 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/frontend/src/app/error/error.component.html b/frontend/src/app/error/error.component.html index a52b913f..f5ffeccf 100644 --- a/frontend/src/app/error/error.component.html +++ b/frontend/src/app/error/error.component.html @@ -6,19 +6,24 @@ <div> <p> An unexpected error occurred.<br/> - <a href="javascript:window.location.reload(true)"> - Refresh the page - </a> - or try later. - <br/> + <a href="javascript:window.location.reload(true)">Refresh the page</a> + <ng-container *ngIf="canGoBack()"> + , <a (click)="goBack();$event.preventDefault()" href="#">go back to the last page</a> + </ng-container> + or retry later. + </p> + <p> Please contact <a href="mailto:urgi-support@inra.fr">urgi-support@inra.fr</a> if the problem persists. </p> - <small *ngIf="error.status" id="error-status"> - Status: {{ error.status }} - </small> - <small *ngIf="error.message" id="error-message"> - Message: {{ error.message }} - </small> + <code *ngIf="error.status || error.message"> + <span *ngIf="error.status" id="error-status"> + Status: {{ error.status }} + </span> + <span *ngIf="error.message" id="error-message"> + <br/> + Message: {{ error.message }} + </span> + </code> </div> </div> </div> diff --git a/frontend/src/app/error/error.component.spec.ts b/frontend/src/app/error/error.component.spec.ts index 07d9e977..d6debb1a 100644 --- a/frontend/src/app/error/error.component.spec.ts +++ b/frontend/src/app/error/error.component.spec.ts @@ -4,6 +4,7 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { Subject } from 'rxjs'; import { ComponentTester, speculoosMatchers } from 'ngx-speculoos'; +import { Location } from '@angular/common'; import { ErrorComponent } from './error.component'; import { ErrorInterceptorService, HttpError } from '../error-interceptor.service'; @@ -38,7 +39,8 @@ describe('ErrorComponent', () => { TestBed.configureTestingModule({ declarations: [ ErrorComponent ], providers: [ - { provide: Router, useValue: { events: routerEvents } } + { provide: Router, useValue: { events: routerEvents } }, + { provide: Location, useValue: { back: () => {} } } ], imports: [ HttpClientTestingModule diff --git a/frontend/src/app/error/error.component.ts b/frontend/src/app/error/error.component.ts index b19ff3b9..c93c9790 100644 --- a/frontend/src/app/error/error.component.ts +++ b/frontend/src/app/error/error.component.ts @@ -3,7 +3,7 @@ import { merge, Observable } from 'rxjs'; import { ErrorInterceptorService, HttpError } from '../error-interceptor.service'; import { NavigationEnd, Router } from '@angular/router'; import { filter, map } from 'rxjs/operators'; - +import { Location } from '@angular/common'; @Component({ selector: 'gpds-error', @@ -14,8 +14,11 @@ export class ErrorComponent { error$: Observable<HttpError | null>; - constructor(private router: Router, - private errorInterceptor: ErrorInterceptorService) { + constructor( + private router: Router, + private errorInterceptor: ErrorInterceptorService, + private location: Location + ) { this.error$ = merge( this.errorInterceptor.getErrors(), this.router.events.pipe( @@ -25,4 +28,11 @@ export class ErrorComponent { ); } + canGoBack(): boolean { + return window.history.length > 1; + } + + goBack(): void { + this.location.back(); + } } diff --git a/frontend/src/app/loading-spinner/loading-spinner.component.ts b/frontend/src/app/loading-spinner/loading-spinner.component.ts index 62e34fb2..3f8f6df4 100644 --- a/frontend/src/app/loading-spinner/loading-spinner.component.ts +++ b/frontend/src/app/loading-spinner/loading-spinner.component.ts @@ -1,4 +1,5 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; +import { ErrorInterceptorService } from '../error-interceptor.service'; @Component({ selector: 'gpds-loading-spinner', @@ -11,8 +12,17 @@ import { Component, Input } from '@angular/core'; } `] }) -export class LoadingSpinnerComponent { +export class LoadingSpinnerComponent implements OnInit { @Input() loading: boolean; + constructor(private errorService: ErrorInterceptorService) { + } + + ngOnInit(): void { + // Force loading stop when an error is intercepted + this.errorService.getErrors().subscribe(() => { + this.loading = false; + }); + } } -- GitLab From 26ec118010b3fa2ba18a6d07639a641cf38e50d7 Mon Sep 17 00:00:00 2001 From: gcornut <guillaume.cornut@inra.fr> Date: Thu, 21 Feb 2019 19:03:16 +0100 Subject: [PATCH 4/6] fix: Fix backend code analysis warning. #5 --- .../gpds/elasticsearch/document/DocumentAnnotationUtil.java | 2 +- .../repository/es/GermplasmAttributeRepositoryImpl.java | 5 +---- .../main/java/fr/inra/urgi/gpds/utils/StringFunctions.java | 6 +++--- .../fr/inra/urgi/gpds/domain/brapi/v1/BrapiMappingTest.java | 2 ++ .../elasticsearch/query/impl/ESGenericQueryFactoryTest.java | 1 + .../urgi/gpds/repository/es/LocationRepositoryTest.java | 2 ++ .../java/fr/inra/urgi/gpds/repository/es/setup/ESSetUp.java | 1 + 7 files changed, 11 insertions(+), 8 deletions(-) diff --git a/backend/src/main/java/fr/inra/urgi/gpds/elasticsearch/document/DocumentAnnotationUtil.java b/backend/src/main/java/fr/inra/urgi/gpds/elasticsearch/document/DocumentAnnotationUtil.java index 0ee1ad94..21878643 100644 --- a/backend/src/main/java/fr/inra/urgi/gpds/elasticsearch/document/DocumentAnnotationUtil.java +++ b/backend/src/main/java/fr/inra/urgi/gpds/elasticsearch/document/DocumentAnnotationUtil.java @@ -26,7 +26,7 @@ public class DocumentAnnotationUtil { * and {@link Nested} annotations */ public static <VO> DocumentMetadata<VO> getDocumentObjectMetadata(Class<VO> valueObjectClass) { - DocumentMetadata<VO> metadata = metadataCache.get(valueObjectClass); + DocumentMetadata metadata = metadataCache.get(valueObjectClass); if (metadata == null) { Document document = valueObjectClass.getAnnotation(Document.class); String valueObjectName = valueObjectClass.getSimpleName(); diff --git a/backend/src/main/java/fr/inra/urgi/gpds/repository/es/GermplasmAttributeRepositoryImpl.java b/backend/src/main/java/fr/inra/urgi/gpds/repository/es/GermplasmAttributeRepositoryImpl.java index e67b06fd..af034811 100644 --- a/backend/src/main/java/fr/inra/urgi/gpds/repository/es/GermplasmAttributeRepositoryImpl.java +++ b/backend/src/main/java/fr/inra/urgi/gpds/repository/es/GermplasmAttributeRepositoryImpl.java @@ -18,8 +18,6 @@ import org.springframework.stereotype.Repository; public class GermplasmAttributeRepositoryImpl implements GermplasmAttributeRepository { - private final ESResponseParser parser; - private ESFindRepository<GermplasmAttributeCriteria, GermplasmAttributeValueListVO> findAttributeRepository; @Autowired @@ -28,9 +26,8 @@ public class GermplasmAttributeRepositoryImpl RestHighLevelClient client, ESRequestFactory requestFactory ) { - this.parser = parser; Class<GermplasmAttributeValueListVO> voClass = GermplasmAttributeValueListVO.class; - findAttributeRepository = new ESGenericFindRepository<>(client, requestFactory, voClass, this.parser); + findAttributeRepository = new ESGenericFindRepository<>(client, requestFactory, voClass, parser); } @Override diff --git a/backend/src/main/java/fr/inra/urgi/gpds/utils/StringFunctions.java b/backend/src/main/java/fr/inra/urgi/gpds/utils/StringFunctions.java index b7852246..6ade272f 100644 --- a/backend/src/main/java/fr/inra/urgi/gpds/utils/StringFunctions.java +++ b/backend/src/main/java/fr/inra/urgi/gpds/utils/StringFunctions.java @@ -1,6 +1,6 @@ package fr.inra.urgi.gpds.utils; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; /** * @author gcornut @@ -12,11 +12,11 @@ public final class StringFunctions { /** * Fixes identifier encoding (in case we have accents in it) */ - public static String asUTF8(String string) throws UnsupportedEncodingException { + public static String asUTF8(String string) { if (string == null) { return null; } - return new String(string.getBytes("ISO-8859-1"), "UTF-8"); + return new String(string.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); } } diff --git a/backend/src/test/java/fr/inra/urgi/gpds/domain/brapi/v1/BrapiMappingTest.java b/backend/src/test/java/fr/inra/urgi/gpds/domain/brapi/v1/BrapiMappingTest.java index 744c9ab5..2b2424ce 100644 --- a/backend/src/test/java/fr/inra/urgi/gpds/domain/brapi/v1/BrapiMappingTest.java +++ b/backend/src/test/java/fr/inra/urgi/gpds/domain/brapi/v1/BrapiMappingTest.java @@ -85,6 +85,7 @@ class BrapiMappingTest { ESGenericQueryFactoryTest.assertJsonEquals(actualJson, expectedJson); } + @SuppressWarnings("unchecked") @Test void should_Deserialize_Additional_Info() throws IOException { String json = additionalInfoExample; @@ -138,6 +139,7 @@ class BrapiMappingTest { ESGenericQueryFactoryTest.assertJsonEquals(actualJson, expectedJson); } + @SuppressWarnings("unchecked") @Test void should_Deserialize_Complex_Brapi_Object() throws IOException { BrapiTrial trial = mapper.readValue(trialExample, TrialVO.class); diff --git a/backend/src/test/java/fr/inra/urgi/gpds/elasticsearch/query/impl/ESGenericQueryFactoryTest.java b/backend/src/test/java/fr/inra/urgi/gpds/elasticsearch/query/impl/ESGenericQueryFactoryTest.java index c0bc3f5c..1f5df4ed 100644 --- a/backend/src/test/java/fr/inra/urgi/gpds/elasticsearch/query/impl/ESGenericQueryFactoryTest.java +++ b/backend/src/test/java/fr/inra/urgi/gpds/elasticsearch/query/impl/ESGenericQueryFactoryTest.java @@ -331,6 +331,7 @@ public class ESGenericQueryFactoryTest { /** * Read package resource in a String */ + @SuppressWarnings("UnstableApiUsage") private String readResource(String path) { try { return CharStreams.toString(new InputStreamReader(getClass().getResourceAsStream(path))); diff --git a/backend/src/test/java/fr/inra/urgi/gpds/repository/es/LocationRepositoryTest.java b/backend/src/test/java/fr/inra/urgi/gpds/repository/es/LocationRepositoryTest.java index 58ed8232..b45c4e96 100644 --- a/backend/src/test/java/fr/inra/urgi/gpds/repository/es/LocationRepositoryTest.java +++ b/backend/src/test/java/fr/inra/urgi/gpds/repository/es/LocationRepositoryTest.java @@ -59,6 +59,7 @@ class LocationRepositoryTest { assertThat(result.getLocationName()).isNotBlank().isEqualTo(result.getName()); } + @SuppressWarnings("deprecation") @Test void should_Have_Same_Abbreviation_And_Abreviation() { // 805 @@ -72,6 +73,7 @@ class LocationRepositoryTest { assertThat(result.getAbbreviation()).isNotBlank().isEqualTo(result.getAbreviation()); } + @SuppressWarnings("deprecation") @Test void should_Have_Same_InstitutionAddress_And_InstitutionAdress() { // 805 diff --git a/backend/src/test/java/fr/inra/urgi/gpds/repository/es/setup/ESSetUp.java b/backend/src/test/java/fr/inra/urgi/gpds/repository/es/setup/ESSetUp.java index abe5e757..7f38d301 100644 --- a/backend/src/test/java/fr/inra/urgi/gpds/repository/es/setup/ESSetUp.java +++ b/backend/src/test/java/fr/inra/urgi/gpds/repository/es/setup/ESSetUp.java @@ -167,6 +167,7 @@ public class ESSetUp { /** * Read package resource in a String */ + @SuppressWarnings("UnstableApiUsage") private String readResource(String path) { try { return CharStreams.toString(new InputStreamReader(getClass().getResourceAsStream(path))); -- GitLab From 4a2e0782863c7e1f27a54cd5448e6e93784c5af8 Mon Sep 17 00:00:00 2001 From: gcornut <guillaume.cornut@inra.fr> Date: Thu, 21 Feb 2019 19:05:07 +0100 Subject: [PATCH 5/6] feat: Animate an opacity pulse on the loading spinner. #5 --- .../loading-spinner.component.scss | 18 ++++++++++++++++++ .../loading-spinner.component.ts | 10 ++++------ 2 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 frontend/src/app/loading-spinner/loading-spinner.component.scss diff --git a/frontend/src/app/loading-spinner/loading-spinner.component.scss b/frontend/src/app/loading-spinner/loading-spinner.component.scss new file mode 100644 index 00000000..6a74cd33 --- /dev/null +++ b/frontend/src/app/loading-spinner/loading-spinner.component.scss @@ -0,0 +1,18 @@ + +.loading { + display: inline-block; + animation: opacityPulse 1.5s infinite ease-in-out; + + i { + color: black; + font-size: 2.2em; + } +} + +$from: 0.3; +$to: 1; +@keyframes opacityPulse { + 0% { opacity: $from; } + 50% { opacity: $to; } + 100% { opacity: $from; } +} diff --git a/frontend/src/app/loading-spinner/loading-spinner.component.ts b/frontend/src/app/loading-spinner/loading-spinner.component.ts index 3f8f6df4..b0c1cef4 100644 --- a/frontend/src/app/loading-spinner/loading-spinner.component.ts +++ b/frontend/src/app/loading-spinner/loading-spinner.component.ts @@ -4,13 +4,11 @@ import { ErrorInterceptorService } from '../error-interceptor.service'; @Component({ selector: 'gpds-loading-spinner', template: ` - <i *ngIf="loading" class="fa fa-spin fa-spinner" title="Loading..."></i> + <div *ngIf="loading" class="loading"> + <i class="fa fa-spin fa-spinner" title="Loading..."></i> + </div> `, - styles: [` - i { - font-size: 2.2em; - } - `] + styleUrls: ['./loading-spinner.component.scss'] }) export class LoadingSpinnerComponent implements OnInit { -- GitLab From 69be1f2ea0c7231999e9577d308ea34ce74b1d8d Mon Sep 17 00:00:00 2001 From: gcornut <guillaume.cornut@inra.fr> Date: Thu, 21 Feb 2019 19:05:45 +0100 Subject: [PATCH 6/6] fix: Add KeyValueObject test. Minor fixes. #5 --- .idea/modules/backend/gpds.backend.test.iml | 2 +- .idea/modules/frontend/gpds.frontend.iml | 4 +++- frontend/src/app/utils.spec.ts | 25 +++++++++++++++++++++ frontend/src/app/utils.ts | 4 ++-- 4 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 frontend/src/app/utils.spec.ts diff --git a/.idea/modules/backend/gpds.backend.test.iml b/.idea/modules/backend/gpds.backend.test.iml index fa6eb121..5f1aabfe 100644 --- a/.idea/modules/backend/gpds.backend.test.iml +++ b/.idea/modules/backend/gpds.backend.test.iml @@ -133,8 +133,8 @@ <orderEntry type="library" name="Gradle: org.junit.platform:junit-platform-commons:1.3.2" level="project" /> <orderEntry type="library" name="Gradle: org.apiguardian:apiguardian-api:1.0.0" level="project" /> <orderEntry type="library" name="Gradle: org.opentest4j:opentest4j:1.1.1" level="project" /> - <orderEntry type="library" scope="RUNTIME" name="Gradle: org.junit.platform:junit-platform-engine:1.3.2" level="project" /> <orderEntry type="library" name="Gradle: javax.annotation:javax.annotation-api:1.3.2" level="project" /> + <orderEntry type="library" scope="RUNTIME" name="Gradle: org.junit.platform:junit-platform-engine:1.3.2" level="project" /> <orderEntry type="library" name="Gradle: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.14" level="project" /> <orderEntry type="library" name="Gradle: org.apache.tomcat.embed:tomcat-embed-core:9.0.14" level="project" /> <orderEntry type="library" name="Gradle: org.apache.tomcat.embed:tomcat-embed-el:9.0.14" level="project" /> diff --git a/.idea/modules/frontend/gpds.frontend.iml b/.idea/modules/frontend/gpds.frontend.iml index 58c4911e..95dbbe14 100644 --- a/.idea/modules/frontend/gpds.frontend.iml +++ b/.idea/modules/frontend/gpds.frontend.iml @@ -5,10 +5,12 @@ <content url="file://$MODULE_DIR$/../../../frontend"> <excludeFolder url="file://$MODULE_DIR$/../../../frontend/.gradle" /> <excludeFolder url="file://$MODULE_DIR$/../../../frontend/build" /> + <excludeFolder url="file://$MODULE_DIR$/../../../frontend/coverage" /> <excludeFolder url="file://$MODULE_DIR$/../../../frontend/dist" /> + <excludeFolder url="file://$MODULE_DIR$/../../../frontend/karma-junit-tests-report" /> <excludeFolder url="file://$MODULE_DIR$/../../../frontend/tmp" /> </content> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> </component> -</module> +</module> \ No newline at end of file diff --git a/frontend/src/app/utils.spec.ts b/frontend/src/app/utils.spec.ts new file mode 100644 index 00000000..104068ba --- /dev/null +++ b/frontend/src/app/utils.spec.ts @@ -0,0 +1,25 @@ +import { KeyValueObject } from './utils'; + + +describe('KeyValueObject', () => { + + it('should convert JS object to array of KeyValueObject', () => { + const actual = KeyValueObject.fromObject({ + 'a': '1', + 'b': '2', + 'c': null, + 'd': '', + '': 'e', + 'f': '3' + }); + + const expected = [ + new KeyValueObject('a', '1'), + new KeyValueObject('b', '2'), + new KeyValueObject('f', '3'), + ]; + + expect(actual).toEqual(expected); + }); + +}); diff --git a/frontend/src/app/utils.ts b/frontend/src/app/utils.ts index 4ff7410e..939ddd37 100644 --- a/frontend/src/app/utils.ts +++ b/frontend/src/app/utils.ts @@ -1,4 +1,4 @@ -export function asArray(obj) { +export function asArray<T>(obj: T | T[]): T[] { if (!obj) { return null; } @@ -17,7 +17,7 @@ export class KeyValueObject { this.value = value; } - static fromObject(o: object): KeyValueObject[] { + static fromObject(o: { [key: string]: string }): KeyValueObject[] { return Object.entries(o) .filter(([key, value]) => !!key && !!value) .map(([key, value]) => new KeyValueObject(key, value)); -- GitLab