Skip to content
Snippets Groups Projects
Commit d272059a authored by François Agneray's avatar François Agneray
Browse files

Search type SVOM Json Keywords => done

parent cca91fbd
No related branches found
No related tags found
2 merge requests!29Develop,!22Svom json kw
Showing
with 322 additions and 69 deletions
...@@ -15,6 +15,7 @@ import * as searchMultiple from './store/reducers/search-multiple.reducer'; ...@@ -15,6 +15,7 @@ import * as searchMultiple from './store/reducers/search-multiple.reducer';
import * as samp from './store/reducers/samp.reducer'; import * as samp from './store/reducers/samp.reducer';
import * as coneSearch from './store/reducers/cone-search.reducer'; import * as coneSearch from './store/reducers/cone-search.reducer';
import * as detail from './store/reducers/detail.reducer'; import * as detail from './store/reducers/detail.reducer';
import * as svomJsonKw from './store/reducers/svom-json-kw.reducer';
/** /**
* Interface for instance state. * Interface for instance state.
...@@ -26,7 +27,8 @@ export interface State { ...@@ -26,7 +27,8 @@ export interface State {
searchMultiple: searchMultiple.State, searchMultiple: searchMultiple.State,
samp: samp.State, samp: samp.State,
coneSearch: coneSearch.State coneSearch: coneSearch.State
detail: detail.State detail: detail.State,
svomJsonKw: svomJsonKw.State
} }
const reducers = { const reducers = {
...@@ -34,7 +36,8 @@ const reducers = { ...@@ -34,7 +36,8 @@ const reducers = {
searchMultiple: searchMultiple.searchMultipleReducer, searchMultiple: searchMultiple.searchMultipleReducer,
samp: samp.sampReducer, samp: samp.sampReducer,
coneSearch: coneSearch.coneSearchReducer, coneSearch: coneSearch.coneSearchReducer,
detail: detail.detailReducer detail: detail.detailReducer,
svomJsonKw: svomJsonKw.svomJsonKwReducer
}; };
export const instanceReducer = combineReducers(reducers); export const instanceReducer = combineReducers(reducers);
......
...@@ -149,6 +149,9 @@ ...@@ -149,6 +149,9 @@
[label]="attribute.form_label" [label]="attribute.form_label"
[criterion]="getCriterion(attribute.id)" [criterion]="getCriterion(attribute.id)"
[criteriaList]="criteriaList" [criteriaList]="criteriaList"
[svomKeywords]="svomKeywords"
(selectSvomAcronym)=selectSvomAcronym.emit($event)
(resetSvomKeywords)="resetSvomKeywords.emit()"
(addCriterion)="emitAdd($event)" (addCriterion)="emitAdd($event)"
(deleteCriterion)="emitDelete($event)"> (deleteCriterion)="emitDelete($event)">
</app-svom-json-kw-criteria> </app-svom-json-kw-criteria>
......
...@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; ...@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CriteriaByFamilyComponent } from './criteria-by-family.component'; import { CriteriaByFamilyComponent } from './criteria-by-family.component';
import { Option } from '../../../../metamodel/models'; import { Option } from '../../../../metamodel/models';
import { Criterion, FieldCriterion } from '../../../store/models'; import { Criterion, FieldCriterion, SvomKeyword } from '../../../store/models';
describe('[Instance][Search][Component][Criteria] CriteriaByFamilyComponent', () => { describe('[Instance][Search][Component][Criteria] CriteriaByFamilyComponent', () => {
@Component({ selector: 'app-field', template: '' }) @Component({ selector: 'app-field', template: '' })
...@@ -123,6 +123,15 @@ describe('[Instance][Search][Component][Criteria] CriteriaByFamilyComponent', () ...@@ -123,6 +123,15 @@ describe('[Instance][Search][Component][Criteria] CriteriaByFamilyComponent', ()
@Input() criterion: Criterion; @Input() criterion: Criterion;
} }
@Component({ selector: 'app-svom-json-kw-criteria', template: '' })
class SvomJsonStubKwComponent {
@Input() id: number;
@Input() label: string;
@Input() criterion: Criterion;
@Input() criteriaList: Criterion[];
@Input() svomKeywords: SvomKeyword[];
}
let component: CriteriaByFamilyComponent; let component: CriteriaByFamilyComponent;
let fixture: ComponentFixture<CriteriaByFamilyComponent>; let fixture: ComponentFixture<CriteriaByFamilyComponent>;
...@@ -142,7 +151,8 @@ describe('[Instance][Search][Component][Criteria] CriteriaByFamilyComponent', () ...@@ -142,7 +151,8 @@ describe('[Instance][Search][Component][Criteria] CriteriaByFamilyComponent', ()
BetweenDateStubComponent, BetweenDateStubComponent,
TimeStubComponent, TimeStubComponent,
DatetimeStubComponent, DatetimeStubComponent,
JsonStubComponent JsonStubComponent,
SvomJsonStubKwComponent
] ]
}); });
fixture = TestBed.createComponent(CriteriaByFamilyComponent); fixture = TestBed.createComponent(CriteriaByFamilyComponent);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core'; import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
import { Criterion } from '../../../store/models'; import { Criterion, SvomKeyword } from '../../../store/models';
import { Attribute, Option } from 'src/app/metamodel/models'; import { Attribute, Option } from 'src/app/metamodel/models';
/** /**
...@@ -24,6 +24,9 @@ import { Attribute, Option } from 'src/app/metamodel/models'; ...@@ -24,6 +24,9 @@ import { Attribute, Option } from 'src/app/metamodel/models';
export class CriteriaByFamilyComponent { export class CriteriaByFamilyComponent {
@Input() attributeList: Attribute[]; @Input() attributeList: Attribute[];
@Input() criteriaList: Criterion[]; @Input() criteriaList: Criterion[];
@Input() svomKeywords: SvomKeyword[];
@Output() selectSvomAcronym: EventEmitter<string> = new EventEmitter();
@Output() resetSvomKeywords: EventEmitter<{}> = new EventEmitter();
@Output() addCriterion: EventEmitter<Criterion> = new EventEmitter(); @Output() addCriterion: EventEmitter<Criterion> = new EventEmitter();
@Output() deleteCriterion: EventEmitter<number> = new EventEmitter(); @Output() deleteCriterion: EventEmitter<number> = new EventEmitter();
......
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
<app-criteria-by-family <app-criteria-by-family
[attributeList]="attributeList | attributeListByFamily:family.id" [attributeList]="attributeList | attributeListByFamily:family.id"
[criteriaList]="criteriaList" [criteriaList]="criteriaList"
[svomKeywords]="svomKeywords"
(selectSvomAcronym)="selectSvomAcronym.emit($event)"
(resetSvomKeywords)="resetSvomKeywords.emit()"
(addCriterion)="emitAdd($event)" (addCriterion)="emitAdd($event)"
(deleteCriterion)="emitDelete($event)"> (deleteCriterion)="emitDelete($event)">
</app-criteria-by-family> </app-criteria-by-family>
......
...@@ -6,7 +6,7 @@ import { AccordionModule } from 'ngx-bootstrap/accordion'; ...@@ -6,7 +6,7 @@ import { AccordionModule } from 'ngx-bootstrap/accordion';
import { CriteriaTabsComponent } from './criteria-tabs.component'; import { CriteriaTabsComponent } from './criteria-tabs.component';
import { Attribute } from '../../../../metamodel/models'; import { Attribute } from '../../../../metamodel/models';
import { Criterion, FieldCriterion } from '../../../store/models'; import { Criterion, FieldCriterion, SvomKeyword } from '../../../store/models';
import { AttributeListByFamilyPipe } from '../../../../shared/pipes/attribute-list-by-family.pipe'; import { AttributeListByFamilyPipe } from '../../../../shared/pipes/attribute-list-by-family.pipe';
describe('[Instance][Search][Component][Criteria] CriteriaTabsComponent', () => { describe('[Instance][Search][Component][Criteria] CriteriaTabsComponent', () => {
...@@ -14,6 +14,7 @@ describe('[Instance][Search][Component][Criteria] CriteriaTabsComponent', () => ...@@ -14,6 +14,7 @@ describe('[Instance][Search][Component][Criteria] CriteriaTabsComponent', () =>
class CriteriaByFamilyStubComponent { class CriteriaByFamilyStubComponent {
@Input() attributeList: Attribute[]; @Input() attributeList: Attribute[];
@Input() criteriaList: Criterion[]; @Input() criteriaList: Criterion[];
@Input() svomKeywords: SvomKeyword[];
} }
let component: CriteriaTabsComponent; let component: CriteriaTabsComponent;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core'; import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
import { Criterion } from '../../../store/models'; import { Criterion, SvomKeyword } from '../../../store/models';
import { CriteriaFamily, Attribute } from 'src/app/metamodel/models'; import { CriteriaFamily, Attribute } from 'src/app/metamodel/models';
/** /**
...@@ -25,6 +25,9 @@ export class CriteriaTabsComponent { ...@@ -25,6 +25,9 @@ export class CriteriaTabsComponent {
@Input() attributeList: Attribute[]; @Input() attributeList: Attribute[];
@Input() criteriaFamilyList: CriteriaFamily[]; @Input() criteriaFamilyList: CriteriaFamily[];
@Input() criteriaList: Criterion[]; @Input() criteriaList: Criterion[];
@Input() svomKeywords: SvomKeyword[];
@Output() selectSvomAcronym: EventEmitter<string> = new EventEmitter();
@Output() resetSvomKeywords: EventEmitter<{}> = new EventEmitter();
@Output() addCriterion: EventEmitter<Criterion> = new EventEmitter(); @Output() addCriterion: EventEmitter<Criterion> = new EventEmitter();
@Output() deleteCriterion: EventEmitter<number> = new EventEmitter(); @Output() deleteCriterion: EventEmitter<number> = new EventEmitter();
......
...@@ -8,14 +8,13 @@ ...@@ -8,14 +8,13 @@
</div> </div>
<div class="w-100 d-block d-sm-none"></div> <div class="w-100 d-block d-sm-none"></div>
<div class="col col-sm-auto mb-1 mb-sm-0 px-sm-0"> <div class="col col-sm-auto mb-1 mb-sm-0 px-sm-0">
<select class="custom-select" id="operator" name="operator" formControlName="operator"> <ng-select [clearable]="false" [multiple]="false" [hideSelected]="true" class="ng-select-custom" formControlName="operator">
<option></option> <ng-option value="eq">=</ng-option >
<option value="eq">=</option> <ng-option value="gt">></ng-option >
<option value="gt">></option> <ng-option value="gte">>=</ng-option >
<option value="gte">>=</option> <ng-option value="lt"><</ng-option >
<option value="lt"><</option> <ng-option value="lte"><=</ng-option >
<option value="lte"><=</option> </ng-select>
</select>
</div> </div>
<div class="w-100 d-block d-sm-none"></div> <div class="w-100 d-block d-sm-none"></div>
<div class="col"> <div class="col">
......
...@@ -2,6 +2,8 @@ import { Component, ViewChild } from '@angular/core'; ...@@ -2,6 +2,8 @@ import { Component, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { NgSelectModule } from '@ng-select/ng-select';
import { JsonComponent } from './json.component'; import { JsonComponent } from './json.component';
import { JsonCriterion } from '../../../../store/models/criterion'; import { JsonCriterion } from '../../../../store/models/criterion';
...@@ -35,7 +37,8 @@ describe('[Instance][Search][Component][Criteria][SearchType] JsonComponent', () ...@@ -35,7 +37,8 @@ describe('[Instance][Search][Component][Criteria][SearchType] JsonComponent', ()
], ],
imports: [ imports: [
FormsModule, FormsModule,
ReactiveFormsModule ReactiveFormsModule,
NgSelectModule
] ]
}); });
testHostFixture = TestBed.createComponent(TestHostComponent); testHostFixture = TestBed.createComponent(TestHostComponent);
......
...@@ -4,26 +4,20 @@ ...@@ -4,26 +4,20 @@
<label>{{ label }}</label> <label>{{ label }}</label>
<div class="row"> <div class="row">
<div class="col mb-1 mb-sm-0"> <div class="col mb-1 mb-sm-0">
<input *ngIf="!acronym" class="form-control" name="ext" placeholder="Ext" autocomplete="off" formControlName="ext"> <input *ngIf="svomKeywords.length < 1" class="form-control" id="path" name="path" placeholder="Path" autocomplete="off" formControlName="path">
<select *ngIf="acronym" class="form-control" name="ext" formControlName="ext" (change)="extOnChange()"> <ng-select *ngIf="svomKeywords.length > 0" [multiple]="false" [hideSelected]="true" placeholder="Select svom product keyword" class="ng-select-custom" formControlName="path">
<option></option> <ng-option *ngFor="let svomKeyword of svomKeywords" [value]="getKeywordValue(svomKeyword)">{{ svomKeyword.extension }}/{{ svomKeyword.name }}</ng-option>
<option *ngFor="let ext of exts" [ngValue]="ext">{{ ext }}</option> </ng-select>
</select>
</div>
<div class="w-100 d-block d-sm-none"></div>
<div class="col mb-1 mb-sm-0 pl-sm-0 pl-md-0 pl-lg-0">
<input *ngIf="!acronym" class="form-control" id="keyword" name="keyword" placeholder="Keyword" autocomplete="off" formControlName="keyword">
</div> </div>
<div class="w-100 d-block d-sm-none"></div> <div class="w-100 d-block d-sm-none"></div>
<div class="col col-sm-auto mb-1 mb-sm-0 px-sm-0"> <div class="col col-sm-auto mb-1 mb-sm-0 px-sm-0">
<select class="custom-select" id="operator" name="operator" formControlName="operator"> <ng-select [clearable]="false" [multiple]="false" [hideSelected]="true" class="ng-select-custom" formControlName="operator">
<option></option> <ng-option value="eq">=</ng-option >
<option value="eq">=</option> <ng-option value="gt">></ng-option >
<option value="gt">></option> <ng-option value="gte">>=</ng-option >
<option value="gte">>=</option> <ng-option value="lt"><</ng-option >
<option value="lt"><</option> <ng-option value="lte"><=</ng-option >
<option value="lte"><=</option> </ng-select>
</select>
</div> </div>
<div class="w-100 d-block d-sm-none"></div> <div class="w-100 d-block d-sm-none"></div>
<div class="col"> <div class="col">
......
import { Component, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { NgSelectModule } from '@ng-select/ng-select';
import { SvomJsonKwComponent } from './svom-json-kw.component';
import { Criterion, JsonCriterion, SvomKeyword } from '../../../../store/models';
describe('[Instance][Search][Component][Criteria][SearchType] SvomJsonKwComponent', () => {
@Component({
selector: `app-host`,
template: `
<app-svom-json-kw-criteria
[id]="id"
[label]="label"
[criterion]="criterion"
[criteriaList]="criteriaList"
[svomKeywords]="svomKeywords">
</app-svom-json-kw-criteria >`
})
class TestHostComponent {
@ViewChild(SvomJsonKwComponent, { static: false })
public testedComponent: SvomJsonKwComponent;
public id: number = undefined;
public label: string = undefined;
public criterion: JsonCriterion = undefined;
public criteriaList: Criterion[] = [];
public svomKeywords: SvomKeyword[] = [];
}
let testHostComponent: TestHostComponent;
let testHostFixture: ComponentFixture<TestHostComponent>;
let testedComponent: SvomJsonKwComponent;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
SvomJsonKwComponent,
TestHostComponent
],
imports: [
FormsModule,
ReactiveFormsModule,
NgSelectModule
]
});
testHostFixture = TestBed.createComponent(TestHostComponent);
testHostComponent = testHostFixture.componentInstance;
testHostFixture.detectChanges();
testedComponent = testHostComponent.testedComponent;
});
it('should create the component', () => {
expect(testedComponent).toBeTruthy();
});
it('should call ngOnChanges and apply changes', () => {
const spy = jest.spyOn(testedComponent, 'ngOnChanges');
testHostComponent.criterion = { id: testedComponent.id, type: 'json', path: 'myPath', operator: 'myOperator', value: 'myValue' } as JsonCriterion;
testHostFixture.detectChanges();
expect(testedComponent.form.controls.path.value).toEqual('myPath');
expect(testedComponent.form.controls.operator.value).toEqual('myOperator');
expect(testedComponent.form.controls.value.value).toEqual('myValue');
expect(testedComponent.form.disabled).toBeTruthy();
testHostComponent.criterion = undefined;
testHostFixture.detectChanges();
expect(testedComponent.form.controls.path.value).toBeNull();
expect(testedComponent.form.controls.operator.value).toBeNull();
expect(testedComponent.form.controls.value.value).toBeNull();
expect(testedComponent.form.enabled).toBeTruthy();
expect(spy).toHaveBeenCalledTimes(2);
});
it('raises the add criterion event when clicked', () => {
testedComponent.id = 1;
testedComponent.form.controls.path.setValue('myPath');
testedComponent.form.controls.operator.setValue('myOperator');
testedComponent.form.controls.value.setValue('myValue');
const expectedCriterion = { id: testedComponent.id, type: 'json', path: 'myPath', operator: 'myOperator', value: 'myValue' } as JsonCriterion;
testedComponent.addCriterion.subscribe((event: JsonCriterion) => expect(event).toEqual(expectedCriterion));
testedComponent.emitAdd();
});
it('Calculates the value of ng-option', () => {
expect(testedComponent.getKeywordValue({
extension: 'PrimaryHDU',
name: 'CARD',
data_type: 'string',
default: ''
})).toEqual('PrimaryHDU,CARD');
});
});
...@@ -8,11 +8,9 @@ ...@@ -8,11 +8,9 @@
*/ */
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, OnChanges, SimpleChanges } from '@angular/core'; import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, OnChanges, SimpleChanges } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { FormGroup, FormControl, Validators } from '@angular/forms'; import { FormGroup, FormControl, Validators } from '@angular/forms';
import { JsonCriterion, Criterion } from 'src/app/instance/store/models'; import { JsonCriterion, Criterion, SvomKeyword } from 'src/app/instance/store/models';
import { AppConfigService } from 'src/app/app-config.service';
@Component({ @Component({
selector: 'app-svom-json-kw-criteria', selector: 'app-svom-json-kw-criteria',
...@@ -24,19 +22,14 @@ export class SvomJsonKwComponent implements OnChanges { ...@@ -24,19 +22,14 @@ export class SvomJsonKwComponent implements OnChanges {
@Input() label: string; @Input() label: string;
@Input() criterion: Criterion; @Input() criterion: Criterion;
@Input() criteriaList: Criterion[]; @Input() criteriaList: Criterion[];
@Input() svomKeywords: SvomKeyword[];
@Output() selectSvomAcronym: EventEmitter<string> = new EventEmitter();
@Output() resetSvomKeywords: EventEmitter<{}> = new EventEmitter();
@Output() addCriterion: EventEmitter<JsonCriterion> = new EventEmitter(); @Output() addCriterion: EventEmitter<JsonCriterion> = new EventEmitter();
@Output() deleteCriterion: EventEmitter<number> = new EventEmitter(); @Output() deleteCriterion: EventEmitter<number> = new EventEmitter();
acronym = false;
keywordsSearchable = null;
exts: string[] = [];
keywords: string[] = [];
public constructor(private httpClient: HttpClient, private config: AppConfigService) { }
public form = new FormGroup({ public form = new FormGroup({
ext: new FormControl('', [Validators.required]), path: new FormControl('', [Validators.required]),
keyword: new FormControl('', [Validators.required]),
operator: new FormControl('', [Validators.required]), operator: new FormControl('', [Validators.required]),
value: new FormControl('', [Validators.required]) value: new FormControl('', [Validators.required])
}); });
...@@ -52,25 +45,23 @@ export class SvomJsonKwComponent implements OnChanges { ...@@ -52,25 +45,23 @@ export class SvomJsonKwComponent implements OnChanges {
this.form.reset(); this.form.reset();
} }
if (changes.criteriaList && changes.criteriaList.currentValue.find((c: Criterion) => c.id === 3)) { if (changes.criteriaList && this.svomKeywords.length < 1 && changes.criteriaList.currentValue.find((c: Criterion) => c.id === 3)) {
this.acronym = true; this.selectSvomAcronym.emit(changes.criteriaList.currentValue.find((c: Criterion) => c.id === 3).value);
this.getKwSearchable(changes.criteriaList.currentValue.find((c: Criterion) => c.id === 3).value);
} }
}
getKwSearchable(acronym: string) { if (changes.criteriaList && this.svomKeywords.length > 0 && !changes.criteriaList.currentValue.find((c: Criterion) => c.id === 3)) {
this.httpClient.get(`${this.config.apiUrl}/search/sp_cards?a=8&c=1::eq::${acronym}`).subscribe(data => { this.resetSvomKeywords.emit();
this.keywordsSearchable = data[0].search_kw; }
this.exts = [...new Set<string>(this.keywordsSearchable.map(item => item.extension))];
console.log(data);
/* this.exts = this.keywordsSearchable
.map(item => item.extension)
.filter((value, index, self) => self.indexOf(value.) === index); */
});
} }
extOnChange() { /**
* Transform a SVOM json Keyword to as path value (anis json search)
*
* @param svomKeyword Keyword selected by user
* @returns string path value
*/
getKeywordValue(svomKeyword: SvomKeyword): string {
return `${svomKeyword.extension},${svomKeyword.name}`
} }
/** /**
...@@ -79,12 +70,7 @@ export class SvomJsonKwComponent implements OnChanges { ...@@ -79,12 +70,7 @@ export class SvomJsonKwComponent implements OnChanges {
* @fires EventEmitter<JsonCriterion> * @fires EventEmitter<JsonCriterion>
*/ */
emitAdd(): void { emitAdd(): void {
const formValue = { const js = { id: this.id, type: 'json', ...this.form.value };
path: `${this.form.controls.ext.value},${this.form.controls.keyword.value}`,
operator: this.form.controls.operator.value,
value: this.form.controls.value.value
}
const js = { id: this.id, type: 'json', ...formValue };
this.addCriterion.emit(js); this.addCriterion.emit(js);
} }
} }
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
[attributeList]="attributeList | async | sortByCriteriaDisplay" [attributeList]="attributeList | async | sortByCriteriaDisplay"
[criteriaFamilyList]="criteriaFamilyList | async" [criteriaFamilyList]="criteriaFamilyList | async"
[criteriaList]="criteriaList | async" [criteriaList]="criteriaList | async"
[svomKeywords]="svomKeywords | async"
(selectSvomAcronym)="selectSvomAcronym($event)"
(resetSvomKeywords)="resetSvomKeywords()"
(addCriterion)="addCriterion($event)" (addCriterion)="addCriterion($event)"
(deleteCriterion)="deleteCriterion($event)"> (deleteCriterion)="deleteCriterion($event)">
</app-criteria-tabs> </app-criteria-tabs>
......
...@@ -6,7 +6,7 @@ import { MockStore, provideMockStore } from '@ngrx/store/testing'; ...@@ -6,7 +6,7 @@ import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { CriteriaComponent } from './criteria.component'; import { CriteriaComponent } from './criteria.component';
import { Attribute, CriteriaFamily, Dataset, OutputCategory, OutputFamily } from '../../../metamodel/models'; import { Attribute, CriteriaFamily, Dataset, OutputCategory, OutputFamily } from '../../../metamodel/models';
import { ConeSearch, Criterion, Resolver, SearchQueryParams } from '../../store/models'; import { ConeSearch, Criterion, Resolver, SearchQueryParams, SvomKeyword } from '../../store/models';
import { SortByCriteriaDisplayPipe } from '../pipes/sort-by-criteria-display.pipe'; import { SortByCriteriaDisplayPipe } from '../pipes/sort-by-criteria-display.pipe';
import * as searchActions from '../../store/actions/search.actions'; import * as searchActions from '../../store/actions/search.actions';
import { AbstractSearchComponent } from './abstract-search.component'; import { AbstractSearchComponent } from './abstract-search.component';
...@@ -31,6 +31,7 @@ describe('[Instance][Search][Container] CriteriaComponent', () => { ...@@ -31,6 +31,7 @@ describe('[Instance][Search][Container] CriteriaComponent', () => {
@Input() attributeList: Attribute[]; @Input() attributeList: Attribute[];
@Input() criteriaFamilyList: CriteriaFamily[]; @Input() criteriaFamilyList: CriteriaFamily[];
@Input() criteriaList: Criterion[]; @Input() criteriaList: Criterion[];
@Input() svomKeywords: SvomKeyword[];
} }
@Component({ selector: 'app-summary', template: '' }) @Component({ selector: 'app-summary', template: '' })
......
...@@ -13,10 +13,12 @@ import { Store } from '@ngrx/store'; ...@@ -13,10 +13,12 @@ import { Store } from '@ngrx/store';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { AbstractSearchComponent } from './abstract-search.component'; import { AbstractSearchComponent } from './abstract-search.component';
import { ConeSearch, Criterion, Resolver } from '../../store/models'; import { ConeSearch, Criterion, Resolver, SvomKeyword } from '../../store/models';
import * as searchActions from '../../store/actions/search.actions'; import * as searchActions from '../../store/actions/search.actions';
import * as coneSearchActions from '../../store/actions/cone-search.actions'; import * as coneSearchActions from '../../store/actions/cone-search.actions';
import * as coneSearchSelector from '../../store/selectors/cone-search.selector'; import * as coneSearchSelector from '../../store/selectors/cone-search.selector';
import * as svomJsonKwActions from '../../store/actions/svom-json-kw.actions';
import * as svomJsonKwSelector from '../../store/selectors/svom-json-kw.selector';
/** /**
* @class * @class
...@@ -30,12 +32,14 @@ export class CriteriaComponent extends AbstractSearchComponent { ...@@ -30,12 +32,14 @@ export class CriteriaComponent extends AbstractSearchComponent {
public resolver: Observable<Resolver>; public resolver: Observable<Resolver>;
public resolverIsLoading: Observable<boolean>; public resolverIsLoading: Observable<boolean>;
public resolverIsLoaded: Observable<boolean>; public resolverIsLoaded: Observable<boolean>;
public svomKeywords: Observable<SvomKeyword[]>;
constructor(protected store: Store<{ }>) { constructor(protected store: Store<{ }>) {
super(store); super(store);
this.resolver = this.store.select(coneSearchSelector.selectResolver); this.resolver = this.store.select(coneSearchSelector.selectResolver);
this.resolverIsLoading = this.store.select(coneSearchSelector.selectResolverIsLoading); this.resolverIsLoading = this.store.select(coneSearchSelector.selectResolverIsLoading);
this.resolverIsLoaded = this.store.select(coneSearchSelector.selectResolverIsLoaded); this.resolverIsLoaded = this.store.select(coneSearchSelector.selectResolverIsLoaded);
this.svomKeywords = this.store.select(svomJsonKwSelector.selectSvomKeywords);
} }
ngOnInit(): void { ngOnInit(): void {
...@@ -88,4 +92,12 @@ export class CriteriaComponent extends AbstractSearchComponent { ...@@ -88,4 +92,12 @@ export class CriteriaComponent extends AbstractSearchComponent {
retrieveCoordinates(name: string): void { retrieveCoordinates(name: string): void {
this.store.dispatch(coneSearchActions.retrieveCoordinates({ name })); this.store.dispatch(coneSearchActions.retrieveCoordinates({ name }));
} }
selectSvomAcronym(acronymSelected: string): void {
this.store.dispatch(svomJsonKwActions.selectAcronym({ acronymSelected }));
}
resetSvomKeywords(): void {
Promise.resolve(null).then(() => this.store.dispatch(svomJsonKwActions.resetKw()));
}
} }
/**
* This file is part of Anis Client.
*
* @copyright Laboratoire d'Astrophysique de Marseille / CNRS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { createAction, props } from '@ngrx/store';
import { SvomKeyword } from '../models';
export const resetKw = createAction('[SVOM Json Kw] Reset Kw');
export const selectAcronym = createAction('[SVOM Json Kw] Select Acronym', props<{ acronymSelected: string }>());
export const loadKwSearchable = createAction('[SVOM Json Kw] Load Kw Searchable');
export const loadKwSearchableSuccess = createAction('[SVOM Json Kw] Load Kw Searchable Success', props<{ svomKeywords: SvomKeyword[] }>());
export const loadKwSearchableFail = createAction('[SVOM Json Kw] Load Kw Searchable Fail');
\ No newline at end of file
...@@ -3,11 +3,13 @@ import { SearchEffects } from './search.effects'; ...@@ -3,11 +3,13 @@ import { SearchEffects } from './search.effects';
import { SearchMultipleEffects } from './search-multiple.effects'; import { SearchMultipleEffects } from './search-multiple.effects';
import { ConeSearchEffects } from './cone-search.effects'; import { ConeSearchEffects } from './cone-search.effects';
import { DetailEffects } from './detail.effects'; import { DetailEffects } from './detail.effects';
import { SvomJsonKwEffects } from './svom-json-kw.effects';
export const instanceEffects = [ export const instanceEffects = [
SampEffects, SampEffects,
SearchEffects, SearchEffects,
SearchMultipleEffects, SearchMultipleEffects,
ConeSearchEffects, ConeSearchEffects,
DetailEffects DetailEffects,
SvomJsonKwEffects
]; ];
import { TestBed } from '@angular/core/testing';
import { provideMockActions } from '@ngrx/effects/testing';
import { EffectsMetadata, getEffectsMetadata } from '@ngrx/effects';
import { provideMockStore } from '@ngrx/store/testing';
import { Observable } from 'rxjs';
import { ToastrService } from 'ngx-toastr';
import { SvomJsonKwEffects } from './svom-json-kw.effects';
import { SvomJsonKwService } from '../services/svom-json-kw.service';
import * as fromSvomJsonKw from '../reducers/svom-json-kw.reducer';
describe('[Instance][Store] SvomJsonKwEffects', () => {
let actions = new Observable();
let effects: SvomJsonKwEffects;
let metadata: EffectsMetadata<SvomJsonKwEffects>;
let svomJsonKwService: SvomJsonKwService;
let toastr: ToastrService;
const initialState = {
instance: {
svomJsonKw: { ...fromSvomJsonKw.initialState }
}
};
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
SvomJsonKwEffects,
{ provide: SvomJsonKwService, useValue: { loadKwSearchable: jest.fn() }},
{ provide: ToastrService, useValue: { success: jest.fn(), error: jest.fn() }},
provideMockActions(() => actions),
provideMockStore({ initialState })
]
}).compileComponents();
effects = TestBed.inject(SvomJsonKwEffects);
metadata = getEffectsMetadata(effects);
svomJsonKwService = TestBed.inject(SvomJsonKwService);
toastr = TestBed.inject(ToastrService);
});
it('should be created', () => {
expect(effects).toBeTruthy();
});
});
/**
* This file is part of Anis Client.
*
* @copyright Laboratoire d'Astrophysique de Marseille / CNRS
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType, concatLatestFrom } from '@ngrx/effects';
import { Store } from '@ngrx/store';
import { of } from 'rxjs';
import { map, tap, mergeMap, catchError } from 'rxjs/operators';
import { ToastrService } from 'ngx-toastr';
import * as svomJsonKwActions from '../actions/svom-json-kw.actions';
import * as svomJsonKwSelector from '../selectors/svom-json-kw.selector';
import { SvomJsonKwService } from '../services/svom-json-kw.service';
/**
* @class
* @classdesc Svom Json Kw effects.
*/
@Injectable()
export class SvomJsonKwEffects {
selectAcronym$ = createEffect((): any =>
this.actions$.pipe(
ofType(svomJsonKwActions.selectAcronym),
map(() => svomJsonKwActions.loadKwSearchable())
)
);
loadKwSearchable$ = createEffect(() =>
this.actions$.pipe(
ofType(svomJsonKwActions.loadKwSearchable),
concatLatestFrom(() => this.store.select(svomJsonKwSelector.selectAcronymSelected)),
mergeMap(([action, acronymSelected]) => this.svomJsonKwService.loadKwSearchable(acronymSelected)
.pipe(
map(svomKeywords => svomJsonKwActions.loadKwSearchableSuccess({ svomKeywords })),
catchError(() => of(svomJsonKwActions.loadKwSearchableFail()))
)
)
)
);
loadKwSearchableSuccess$ = createEffect(() =>
this.actions$.pipe(
ofType(svomJsonKwActions.loadKwSearchableSuccess),
tap(() => {
this.toastr.success('SVOM Json Keywords was loaded successfully and are now available to product criteria', 'SVOM Json Keywords loaded')
})
), { dispatch: false}
);
addDatabaseFail$ = createEffect(() =>
this.actions$.pipe(
ofType(svomJsonKwActions.loadKwSearchableFail),
tap(() => this.toastr.error('Failure to load Keywords', 'SVOM Json Keywords loaded failed'))
), { dispatch: false}
);
constructor(
private actions$: Actions,
private store: Store<{ }>,
private svomJsonKwService: SvomJsonKwService,
private toastr: ToastrService
) {}
}
...@@ -7,3 +7,4 @@ export * from './cone-search.model'; ...@@ -7,3 +7,4 @@ export * from './cone-search.model';
export * from './resolver.model'; export * from './resolver.model';
export * from './search-multiple-dataset-length'; export * from './search-multiple-dataset-length';
export * from './search-multiple-dataset-data'; export * from './search-multiple-dataset-data';
export * from './svom-keyword.model';
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment