Commit 51c7f314 authored by Jérémy Destin's avatar Jérémy Destin
Browse files

fix: Fix the consistency between the switch on/off button and the display of...

fix: Fix the consistency between the switch on/off button and the display of the germplasm results. Isolate the facets in a component to manage the large or small display of the facets. GNP-4309.
parent 07ae6258
......@@ -28,7 +28,7 @@ import { DocumentComponent } from './result-page/document/document.component';
import { ErrorComponent } from './error/error.component';
import { ErrorInterceptorService } from './error-interceptor.service';
import { TraitOntologyWidgetComponent } from './form/trait-ontology-widget/trait-ontology-widget.component';
import { FacetsComponent } from './result-page/facets/facets.component';
import { FacetsComponent } from './facets/facets.component';
import { CardRowComponent } from './card-row/card-row.component';
import { CardSectionComponent } from './card-section/card-section.component';
import { LoadingSpinnerComponent } from './loading-spinner/loading-spinner.component';
......@@ -40,7 +40,8 @@ import { CardGenericDocumentComponent } from './card-generic-document/card-gener
import { MarkdownModule, MarkedOptions, MarkedRenderer } from 'ngx-markdown';
import { MarkdownPageComponent } from './markdown-page/markdown-page.component';
import { DecimalPipe } from '@angular/common';
import { LargeFacetsComponent } from './result-page/large-facets/large-facets.component';
import { LargeFacetsComponent } from './facets/large-facets/large-facets.component';
import { SmallFacetsComponent } from './facets/small-facets/small-facets.component';
@NgModule({
declarations: [
......@@ -66,7 +67,8 @@ import { LargeFacetsComponent } from './result-page/large-facets/large-facets.co
XrefsComponent,
CardGenericDocumentComponent,
MarkdownPageComponent,
LargeFacetsComponent
LargeFacetsComponent,
SmallFacetsComponent
],
imports: [
BrowserModule,
......
<div class="row">
<faidare-small-facets
class="col-12 col-lg-12 col-sm-6"
*ngFor="let facet of facets"
[criteria$]="criteria$"
[facet]="facet"
[germplasmSearchCriteria$]="germplasmSearchCriteria$"
[displayGermplasmResult$]="displayGermplasmResult$">
</faidare-small-facets>
</div>
<div class="row">
<faidare-large-facets
class="col-12 col-lg-12 col-sm-6"
*ngFor="let facet of facets"
[criteria$]="criteria$"
[facet]="facet"
[germplasmSearchCriteria$]="germplasmSearchCriteria$">
</faidare-large-facets>
</div>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FacetsComponent } from './facets.component';
describe('LargeFacetsComponent', () => {
let component: FacetsComponent;
let fixture: ComponentFixture<FacetsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [FacetsComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(FacetsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, Input, OnInit } from '@angular/core';
import {
DataDiscoveryCriteria,
DataDiscoveryFacet
} from '../models/data-discovery.model';
import { BehaviorSubject } from 'rxjs';
import { GermplasmSearchCriteria } from '../models/gnpis.model';
@Component({
selector: 'faidare-facets',
templateUrl: './facets.component.html',
styleUrls: ['./facets.component.scss']
})
export class FacetsComponent implements OnInit {
@Input() facets: DataDiscoveryFacet[];
@Input() criteria$: BehaviorSubject<DataDiscoveryCriteria>;
@Input() germplasmSearchCriteria$: BehaviorSubject<GermplasmSearchCriteria>;
@Input() displayGermplasmResult$: BehaviorSubject<boolean>;
constructor() {
}
ngOnInit(): void {
}
}
<ng-template #resultTemplate let-facet="result" let-t="term">
<ng-container *ngIf="facet !== 'REFINE'; else refine">
<ngb-highlight [result]="displayableKey(facet.label)" [term]="t"></ngb-highlight>
<ngb-highlight [result]="displayableKey(facet.label)"
[term]="t"></ngb-highlight>
<small class="ml-1 text-muted">({{ facet.count | number }})</small>
</ng-container>
<ng-template #refine>
<div class="text-muted small">Other results are available.<br/>Refine your search.</div>
<div class="text-muted small">Other results are available.<br/>Refine your
search.
</div>
</ng-template>
</ng-template>
<div class="mb-2">
<span class="badge badge-pill badge-secondary mr-1" *ngFor="let term of selectedTerms[facet.field]" tabindex="0"
<ng-container *ngIf="facet.terms.length && facet.terms.length > 8">
<div class="mb-2">
<span class="badge badge-pill badge-secondary mr-1"
*ngFor="let term of selectedTerms[facet.field]" tabindex="0"
(keydown.delete)="removeKey(term)"
(keydown.backspace)="removeKey(term)"> {{ displaySourceName(term) }}
<button tabindex="-1" type="button" class="btn btn-link" (click)="removeKey(term)">&times;</button>
<button tabindex="-1" type="button" class="btn btn-link"
(click)="removeKey(term)">&times;</button>
</span>
</div>
<div class="card mb-1" *ngIf="facet.terms.length">
<div class="card-body">
<h3 class="card-title">{{ facet.field | titlecase }}</h3>
</div>
<div class="card mb-1" *ngIf="facet.terms.length">
<div class="card-body">
<h3 class="card-title">{{ facet.field | titlecase }}</h3>
<input #typeahead class="form-control" [formControl]="criterion"
[ngbTypeahead]="search"
(selectItem)="selectKey($event)" [resultTemplate]="resultTemplate"
placeholder="Filter on {{ facet.field.toLowerCase() }}..."
(focus)="focus$.next($event.target.value)"/>
</div>
</div>
</div>
</ng-container>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { LargeFacetsComponent } from './large-facets.component';
describe('LargeFacetsComponent', () => {
let component: LargeFacetsComponent;
let fixture: ComponentFixture<LargeFacetsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [LargeFacetsComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LargeFacetsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
......@@ -116,10 +116,10 @@ export class LargeFacetsComponent implements OnInit {
}
}
if (this.germplasmSearchCriteria$) {
if (this.germplasmLocalCriteria[this.facet.field]) {
this.germplasmLocalCriteria[this.facet.field].push(event.item.term);
} else {
if (!this.germplasmLocalCriteria[this.facet.field]) {
this.germplasmLocalCriteria[this.facet.field] = [event.item.term];
} else {
this.germplasmLocalCriteria[this.facet.field].push(event.item.term);
}
}
this.emitChanges();
......
<div class="card mb-1" *ngIf="facet.terms.length">
<div class="card mb-1" *ngIf="facet.terms.length && facet.terms.length < 8">
<div class="card-body">
<h3 class="card-title">{{ facet.field | titlecase }}</h3>
......@@ -11,23 +11,21 @@
/>
<label class="form-check-label" for="{{ term.term }}">
{{ term.label }} ({{ term.count | number }})
</label>
<div id="germplasmSearch"
title="Focus on germplasm details with export data link"
*ngIf="term.term == 'Germplasm' && !criteriaIsEmpty">
<label for="selectSwitchButton" style="margin-right: 5px"
id="switchTitle"
>
id="switchTitle">
Focus
</label>
<label class="switch" id="switchButton">
<input type="checkbox" id="selectSwitchButton"
[checked]="displayGermplasmCurrentState"
(change)="switchToGermplasmResult()">
<span class="slider round"></span>
</label>
</div>
</div>
</form>
......
......@@ -12,8 +12,6 @@
cursor: pointer;
}
/* The switch - the box around the slider */
.switch {
......@@ -76,3 +74,4 @@ input:checked + .slider:before {
.slider.round:before {
border-radius: 50%;
}
import { TestBed } from '@angular/core/testing';
import { FacetsComponent } from './facets.component';
import { SmallFacetsComponent } from './small-facets.component';
import { ReactiveFormsModule } from '@angular/forms';
import { ComponentTester, speculoosMatchers } from 'ngx-speculoos';
import { DataDiscoveryCriteria, DataDiscoveryCriteriaUtils, DataDiscoveryFacet } from '../../models/data-discovery.model';
import {
DataDiscoveryCriteria,
DataDiscoveryCriteriaUtils,
DataDiscoveryFacet
} from '../../models/data-discovery.model';
import { BehaviorSubject } from 'rxjs';
import { take } from 'rxjs/operators';
import { NO_ERRORS_SCHEMA } from '@angular/core';
describe('FacetsComponent', () => {
class FacetsComponentTester extends ComponentTester<FacetsComponent> {
describe('SmallFacetsComponent', () => {
class FacetsComponentTester extends ComponentTester<SmallFacetsComponent> {
constructor() {
super(FacetsComponent);
super(SmallFacetsComponent);
}
get title() {
......@@ -61,7 +64,7 @@ describe('FacetsComponent', () => {
beforeEach(() => TestBed.configureTestingModule({
imports: [ReactiveFormsModule],
declarations: [FacetsComponent],
declarations: [SmallFacetsComponent],
schemas: [NO_ERRORS_SCHEMA]
}));
......
import { Component, Input, OnInit } from '@angular/core';
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import {
DataDiscoveryCriteria,
DataDiscoveryCriteriaUtils,
......@@ -11,17 +11,19 @@ import { Params } from '@angular/router';
import { GermplasmSearchCriteria } from '../../models/gnpis.model';
@Component({
selector: 'faidare-facets',
templateUrl: './facets.component.html',
styleUrls: ['./facets.component.scss']
selector: 'faidare-small-facets',
templateUrl: './small-facets.component.html',
styleUrls: ['./small-facets.component.scss']
})
export class FacetsComponent implements OnInit {
export class SmallFacetsComponent implements OnInit {
@Input() facet: DataDiscoveryFacet;
@Input() criteria$: BehaviorSubject<DataDiscoveryCriteria>;
@Input() germplasmSearchCriteria$: BehaviorSubject<GermplasmSearchCriteria>;
@Input() displayGermplasmResult$: BehaviorSubject<boolean>;
@Output() changed = new EventEmitter<boolean>();
localCriteria: DataDiscoveryCriteria;
germplasmLocalCriteria: GermplasmSearchCriteria;
......@@ -29,6 +31,7 @@ export class FacetsComponent implements OnInit {
queryParams: Params;
checkBoxes: FormGroup = new FormGroup({});
displayAdvanceGermplasmSearchButton: boolean;
displayGermplasmCurrentState = false;
constructor() {
}
......@@ -74,28 +77,16 @@ export class FacetsComponent implements OnInit {
this.criteria$.next(this.localCriteria);
}
if (this.germplasmSearchCriteria$) {
const field = this.facet.field;
if (field === 'holding institute') {
this.germplasmLocalCriteria = {
...this.germplasmLocalCriteria,
holdingInstitute: selectedTerms
};
}
if (field === 'Biological status / Genetic nature') {
this.germplasmLocalCriteria = {
...this.germplasmLocalCriteria,
biologicalStatus: selectedTerms,
geneticNature: selectedTerms
};
}
if (field !== 'Biological status / Genetic nature' && field !== 'holding institute') {
this.germplasmLocalCriteria = {
...this.germplasmLocalCriteria,
[this.facet.field]: selectedTerms
};
}
this.germplasmSearchCriteria$.next(this.germplasmLocalCriteria);
this.germplasmLocalCriteria = {
...this.germplasmLocalCriteria,
[this.facet.field]: selectedTerms
};
}
this.germplasmSearchCriteria$.next(this.germplasmLocalCriteria);
});
this.displayGermplasmResult$.subscribe(value => {
this.displayGermplasmCurrentState = value;
});
}
......@@ -119,15 +110,13 @@ export class FacetsComponent implements OnInit {
}
switchToGermplasmResult() {
let currentState = false;
this.displayGermplasmResult$.subscribe(value => {
currentState = value;
});
for (const [key, control] of Object.entries(this.checkBoxes.controls)) {
/*for (const [key, control] of Object.entries(this.checkBoxes.controls)) {
if (key === 'selectSwitchButton') {
control.setValue(currentState, { emitEvent: false });
}
}
this.displayGermplasmResult$.next(!currentState);
}*/
this.displayGermplasmResult$.next(!this.displayGermplasmCurrentState);
}
}
......@@ -27,6 +27,11 @@
height="20px"/>
</button>
<!-- Loading spinner-->
<div class="text-center">
<faidare-loading-spinner [loading]="loading"></faidare-loading-spinner>
</div>
<faidare-card-section
class="col-12 col-lg"
header="Germplasm data: "
......
......@@ -33,6 +33,7 @@ export class GermplasmResultPageComponent implements OnInit {
headers: string[] = ['germplasmName', 'accessionNumber', 'commonCropName', 'instituteName'];
elementPerPage: number[] = [15, 20, 25];
loading: boolean;
fieldSortState: object = {
germplasmName: null,
accessionNumber: null,
......@@ -75,7 +76,7 @@ export class GermplasmResultPageComponent implements OnInit {
this.service.germplasmSearch(criteria)
.subscribe(({ metadata, facets, result }) => {
this.germplasm = result.data;
this.germplasmFacets$.next(this.formatFacets(facets));
this.germplasmFacets$.next(facets);
DataDiscoveryCriteriaUtils.updatePagination(this.pagination, metadata.pagination);
});
}
......@@ -109,10 +110,12 @@ export class GermplasmResultPageComponent implements OnInit {
}
exportPlantMaterial(criteria: GermplasmSearchCriteria) {
this.loading = true;
this.service.plantMaterialExport(criteria).subscribe(
result => {
const blob = new Blob([result], { type: 'text/plain;charset=utf-8' });
saveAs(blob, 'germplasm.gnpis.csv');
this.loading = false;
},
error => {
console.log(error);
......
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { LargeFacetsComponent } from './large-facets.component';
describe('LargeFacetsComponent', () => {
let component: LargeFacetsComponent;
let fixture: ComponentFixture<LargeFacetsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LargeFacetsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LargeFacetsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
......@@ -3,38 +3,21 @@
<div class="row justify-content-end">
<!-- Column for facets -->
<div class="col-lg-3 order-lg-first">
<div class="row">
<faidare-facets
class="col-12 col-lg-12 col-sm-6"
*ngFor="let facet of facets"
[criteria$]="criteria$"
[facet]="facet"
[displayGermplasmResult$]="displayGermplasmResult$">
</faidare-facets>
</div>
<!--<div class="row" *ngIf="germplasmfacets.length && displayGermplasmResult">
<faidare-facets
class="col-12 col-lg-12 col-sm-6"
*ngFor="let facet of germplasmfacets"
[germplasmSearchCriteria$]="germplasmSearchCriteria$"
[facet]="facet"
[displayGermplasmResult$]="displayGermplasmResult$">
</faidare-facets>
</div>-->
<div class="row" *ngIf="germplasmfacets.length && displayGermplasmResult">
<faidare-large-facets
class="col-12 col-lg-12 col-sm-6"
*ngFor="let facet of germplasmfacets"
[criteria$]="criteria$"
[facet]="facet"
[germplasmSearchCriteria$]="germplasmSearchCriteria$">
</faidare-large-facets>
</div>
<faidare-facets
[criteria$]="criteria$"
[facets]="facets"
[displayGermplasmResult$]="displayGermplasmResult$"
[germplasmSearchCriteria$]="germplasmSearchCriteria$">
</faidare-facets>
<faidare-facets
*ngIf="displayGermplasmResult && germplasmfacets.length"
[criteria$]="criteria$"
[facets]="germplasmfacets"
[displayGermplasmResult$]="displayGermplasmResult$"
[germplasmSearchCriteria$]="germplasmSearchCriteria$">
</faidare-facets>
</div>
<!-- Column for form and results-->
......@@ -134,7 +117,8 @@
</ng-container>
<!-- Else we display a simple message when no result found -->
<div *ngIf="pagination.totalResult == 0 && !loading && !criteriaIsEmpty"
<div *ngIf="pagination.totalResult == 0 && !loading
&& (!criteriaIsEmpty && !displayGermplasmResult)"
id="no-results" class="text-center">
<div class="no-result-icon">
<span class="fa fa-meh-o"></span>
......
......@@ -113,7 +113,6 @@ export class ResultPageComponent implements OnInit {
this.criteria$
.pipe(filter(c => c !== initialCriteria))
.subscribe(newCriteria => {
this.displayGermplasmResult = false;
// Reset pagination
newCriteria.page = 0;
// Fetch documents and facets
......@@ -131,9 +130,10 @@ export class ResultPageComponent implements OnInit {
this.displayGermplasmResult$.next(this.displayGermplasmResult);
});
this.displayGermplasmResult$.subscribe(value => {
/*this.displayGermplasmResult$.subscribe(value => {
this.displayGermplasmResult = value;
});
this.displayGermplasmResult$.next(this.displayGermplasmResult);*/
this.germplasmfacets$.subscribe(facets => {
this.germplasmfacets = facets;
......
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