Add search in refine fields for autocomplete used in advanced search, autocoplete from vocabularies/ refine and keyword for all fields in publications advanced search page

git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-services-portal/trunk@44343 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
argiro.kokogiannaki 2016-10-26 15:23:18 +00:00
parent e633b7e234
commit 4d8b8ff9a9
17 changed files with 348 additions and 153 deletions

View File

@ -5,7 +5,7 @@ import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.cl
import {SearchPublicationsService} from '../../services/searchPublications.service';
import {SearchResult} from '../../utils/entities/searchResult';
import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties';
import {AdvancedSearchPageComponent} from '../searchUtils/advancedSearchPage.component';
import {SearchFields} from '../../utils/properties/searchFields';
@ -13,21 +13,17 @@ import {SearchFields} from '../../utils/properties/searchFields';
@Component({
selector: 'advanced-search-publications',
template: `
<advanced-search-page pageTitle="Advanced Search Publications" type="publication"
<advanced-search-page pageTitle="Advanced Search Publications" entityType="publication"
[(results)] = "results" [(totalResults)] = "totalResults"
[(page)] = "page" [(size)] = "size" [baseUrl] = "baseUrl"
[(fieldIds)]="fieldIds" [(selectedFields)]="selectedFields"
[(status)] = "status"
(queryChange)="queryChanged($event)">
</advanced-search-page>
`
})
/*
[(filters)] = "filters"
[(fields)] = "fields" [(selectedFields)]="selectedFields"
[(quantifiers)]="quantifiers" [(selectedQuantifiers)]="selectedQuantifiers"
[(keywords)] = "keywords"
*/
export class AdvancedSearchPublicationsComponent {
private results =[];
private filters =[];
@ -38,12 +34,10 @@ export class AdvancedSearchPublicationsComponent {
private baseUrl: string;
private searchFields:SearchFields = new SearchFields();
//"all", "title", "author", "date","project",
private fieldIds: string[] = ["funder","funderlv0","funderlv1","funderlv2","lang","type"];
//this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.fieldIds[0]].type
private selectedFields:AdvancedField[] = [new AdvancedField(this.fieldIds[0],this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.fieldIds[0]].name,"keyword","")];
private fieldIds: string[] = this.searchFields.ADVANCED_SEARCH_PUBLICATIONS_FIELDS;
private selectedFields:AdvancedField[] = [];
@ViewChild (AdvancedSearchPageComponent) searchPage : AdvancedSearchPageComponent ;
constructor (private route: ActivatedRoute, private _searchPublicationsService: SearchPublicationsService ) {
@ -57,27 +51,27 @@ export class AdvancedSearchPublicationsComponent {
}
ngOnInit() {
console.log(this.fieldIds[0]+" "+this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.fieldIds[0]].name);
// console.log(this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.fieldIds[0]].type);
this.sub = this.route.queryParams.subscribe(params => {
var errorCodes:ErrorCodes = new ErrorCodes();
this.status =errorCodes.LOADING;
this.sub = this.route.queryParams.subscribe(params => {
let page = (params['page']=== undefined)?1:+params['page'];
// let size = (params['size']=== undefined)?10:+params['size'];
this.page = ( page <= 0 ) ? 1 : page;
// this.size = ( size <= 0 ) ? 10 : size;
//this.keywords = (params['keyword']?params['keyword']:'');
this.searchPage.fieldIds = this.fieldIds;
this.searchPage.selectedFields = this.selectedFields;
this.searchPage.getSelectedFiltersFromUrl(params);
this.getResults(this.searchPage.createQueryParameters(), this.page, this.size);
});
//TODO get the rest parameters to create query
}
ngOnDestroy() {
this.sub.unsubscribe();
}
sub: any;
public getResults(parameters:string, page: number, size: number){
var errorCodes:ErrorCodes = new ErrorCodes();
this.status = errorCodes.LOADING;
console.info("Advanced Search Publications: Execute search query "+parameters);
this._searchPublicationsService.searchPublications(parameters, null, page, size, []).subscribe(
this._searchPublicationsService.searchPublications(parameters, null, page, size, []).subscribe(
data => {
this.totalResults = data[0];
console.info("searchPubl total="+this.totalResults);

View File

@ -84,8 +84,8 @@ export class SearchProjectsComponent {
this.totalResults = data[0];
console.info("search Projects: [Parameters:"+parameters+" ] [total results:"+this.totalResults+"]");
this.results = data[1];
this.filters = this.searchPage.checkSelectedFilters(data[2]);
this.searchPage.updateBaseUrlWithParameters(this.filters);
this.filters = this.searchPage.checkSelectedFilters(data[2]);
this.searchPage.updateBaseUrlWithParameters(this.filters);
var errorCodes:ErrorCodes = new ErrorCodes();
this.status = errorCodes.DONE;
if(this.totalResults == 0 ){

View File

@ -12,17 +12,17 @@ import {SearchFields} from '../../utils/properties/searchFields';
<div *ngFor="let selectedField of selectedFields; let i = index" class="form-group form-inline">
<div *ngIf = "i != 0" class="input-group">
<button [style.width]="'120px'" type="button" id="dropdownMenu1" data-toggle="dropdown" class="btn btn-default dropdown-toggle" aria-haspopup="true" aria-expanded="true">
{{selectedField.operatorName}}
{{selectedField.operatorId}}
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li *ngFor="let op of operators">
<a (click)="fieldOperatorChanged(i, op.id, op.name)">{{op.name}}</a>
<a (click)="fieldOperatorChanged(i, op.id, op.id)">{{op.id}}</a>
</li>
</ul>
</div>
<div class="input-group">
<div class="input-group-btn">
<button [style.width]="'120px'" aria-expanded="false" aria-haspopup="true" class="btn btn-default dropdown-toggle" data-toggle="dropdown" id="dropdownMenu1" type="button">
<button aria-expanded="false" aria-haspopup="true" class="btn btn-default dropdown-toggle" data-toggle="dropdown" id="dropdownMenu1" type="button">
{{selectedField.name}}
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
@ -34,11 +34,14 @@ import {SearchFields} from '../../utils/properties/searchFields';
<input *ngIf = "searchFields.ADVANCED_FIELDS_NAMES_IDS[selectedField.id].type == 'keyword'" type="text" class="form-control" placeholder="Type keywords..." [(ngModel)]="selectedField.value" name="value[{{i}}]">
<div *ngIf = "searchFields.ADVANCED_FIELDS_NAMES_IDS[selectedField.id].type == 'vocabulary'" class="input-group">
<static-autocomplete2 [vocabularyId] = selectedField.id [selectedValue]=selectedField.value [showSelected]=true [placeHolderMessage] = "'Search for '+selectedField.name" title = "Languages:" [multipleSelections]=false (selectedValueChanged)="valueChanged($event,i)"></static-autocomplete2>
</div>
<div *ngIf = "searchFields.ADVANCED_FIELDS_NAMES_IDS[selectedField.id].type == 'refine'" class="input-group">
<static-autocomplete2 [entityName] = "entityType" [fieldName] = searchFields.ADVANCED_FIELDS_NAMES_IDS[selectedField.id].indexField [selectedValue]=selectedField.value [showSelected]=true [placeHolderMessage] = "'Search for '+selectedField.name" title = "Languages:" [multipleSelections]=false (selectedValueChanged)="valueChanged($event,i)"></static-autocomplete2>
</div>
</div>
<div *ngIf = "searchFields.ADVANCED_FIELDS_NAMES_IDS[selectedField.id].type == 'staticAutoComplete'" class="input-group">
<static-autocomplete2 [vocabularyId] = selectedField.id [(selectedId)]=selectedField.value [showSelected]=true [placeHolderMessage] = "'Search for '+selectedField.name" title = "Languages:" [multipleSelections]=false ></static-autocomplete2>
</div>
<button type="button" class="btn btn-success" (click)="addField()">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
@ -55,15 +58,15 @@ import {SearchFields} from '../../utils/properties/searchFields';
`
})
///[style.width]="'120px'"
export class AdvancedSearchFormComponent {
@Input() entityType;
@Input() fieldIds: string[];
@Input() selectedFields:AdvancedField[];
@Output() queryChange = new EventEmitter();
private searchFields:SearchFields = new SearchFields();
private operators: [{name:string, id:string}] = [{name:"AND",id:"and"},{name:"OR",id:"or"},{name:"NOT",id:"not"}];
private operators: [{name:string, id:string}] = this.searchFields.ADVANCED_SEARCH_OPERATORS;
constructor () {
}
@ -80,7 +83,7 @@ export class AdvancedSearchFormComponent {
addField() {
console.info("add filter"+this.fieldIds[0]+this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.fieldIds[0]].name+this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.fieldIds[0]].type);
this.selectedFields.push(new AdvancedField(this.fieldIds[0], this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.fieldIds[0]].name,this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.fieldIds[0]].type,""));
this.selectedFields.push(new AdvancedField(this.fieldIds[0], this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.fieldIds[0]].name,this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.fieldIds[0]].type,"","and"));
}
@ -99,5 +102,10 @@ export class AdvancedSearchFormComponent {
this.selectedFields[index].id = id;
this.selectedFields[index].name = this.searchFields.ADVANCED_FIELDS_NAMES_IDS[id].name;
this.selectedFields[index].type = this.searchFields.ADVANCED_FIELDS_NAMES_IDS[id].type;
this.selectedFields[index].value = "";
}
valueChanged($event,index:number){
console.log("Changed!"+index+$event.value)
this.selectedFields[index].value = $event.value;
}
}

View File

@ -28,6 +28,7 @@ import {SearchFields} from '../../utils/properties/searchFields';
[(keywords)]="keywords"
<div class="col-xs-6 col-sm-9 sidebar-offcanvas" id="sidebar"-->
<advanced-search-form
[entityType] = "entityType"
[(fieldIds)]="fieldIds" [(selectedFields)]="selectedFields"
(queryChange)="queryChanged($event)">
</advanced-search-form>
@ -37,7 +38,7 @@ import {SearchFields} from '../../utils/properties/searchFields';
</div>
<div>
<search-result [results]="results" [page]="page"></search-result>
<search-result [results]="results" [status]=status [page]="page"></search-result>
</div>
<!--/div>
</div-->
@ -49,30 +50,20 @@ import {SearchFields} from '../../utils/properties/searchFields';
export class AdvancedSearchPageComponent {
@Input() pageTitle = "";
@Input() results = [];
// @Input() filters = [];
@Input() type;
@Input() entityType;
@Input() page:number = 1;
@Input() size: number = 10;
@Input() totalResults: number = 0;
@Input() fieldIds: string[];
@Input() selectedFields:AdvancedField[];
@Input() baseUrl:string = '';
@Input() status: number;
private baseURLWithParameters:string = '';
private searchFields:SearchFields = new SearchFields();
// @Input() fields: {"name": string, "value": string}[];
// @Input() selectedFields: {"name": string, "value": string}[];
// @Input() quantifiers: {"name": string, "value": string}[];
// @Input() selectedQuantifiers: {"name": string, "value": string}[];
// @Input() keywords:string[];
//
// @Output() keywordsChange = new EventEmitter();
//
// test= { value: 0};
@Output() queryChange = new EventEmitter();
constructor (private location: Location) {
@ -81,18 +72,58 @@ export class AdvancedSearchPageComponent {
ngOnInit() {
this.totalResults = this.results.length;
}
public getSelectedFiltersFromUrl(params){
for(var i=0; i< this.fieldIds.length ; i++){
var fieldId = this.fieldIds[i];
var operatorId = this.searchFields.ADVANCED_FIELDS_NAMES_IDS[fieldId].operator;
if(params[fieldId] != undefined && params[operatorId] != undefined) {
console.log(fieldId + " " + params[fieldId]+" Op: "+ operatorId + " "+ params[operatorId] );
var values:string [] = decodeURIComponent(params[fieldId]).split(",");
var operators:string [] = decodeURIComponent(params[operatorId]).split(",");
console.log(values + " " + " Op: "+ operators );
if(values.length == operators.length){
for(var j=0; j< values.length ; j++){
this.selectedFields.push(new AdvancedField(fieldId,this.searchFields.ADVANCED_FIELDS_NAMES_IDS[fieldId].name,this.searchFields.ADVANCED_FIELDS_NAMES_IDS[fieldId].type,values[j],operators[j]) )
}
}
}
}
if(this.selectedFields.length == 0){
this.selectedFields.push(new AdvancedField(this.fieldIds[0],this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.fieldIds[0]].name,this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.fieldIds[0]].type,"","and"));
}
}
private createUrlParameters(includePage:boolean){
var params="";
var fields: { [key:string]:{ values:string[], operators:string[] }}={};
for(var i = 0; i< this.selectedFields.length; i++){
if(this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.selectedFields[i].id] != undefined && this.selectedFields[i].value.length > 0){
if(!fields[this.selectedFields[i].id]){
fields[this.selectedFields[i].id] = {values:[], operators:[]};
fields[this.selectedFields[i].id].values =[];
fields[this.selectedFields[i].id].operators =[];
}
fields[this.selectedFields[i].id].values.push(this.selectedFields[i].value);
fields[this.selectedFields[i].id].operators.push(this.selectedFields[i].operatorId);
}
}
for(var i = 0; i< this.fieldIds.length; i++){
if(fields[this.fieldIds[i]]){
params+="&"+this.fieldIds[i]+"="+fields[this.fieldIds[i]].values.join()+
"&"+this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.fieldIds[i]].operator+"="+fields[this.fieldIds[i]].operators.join()
}
}
if(includePage && this.page != 1){
params += "&page="+this.page;
}
return "";
return params;
}
private createQueryParameters(){
public createQueryParameters(){
var params="";
for(var i = 0; i< this.selectedFields.length; i++){
if(this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.selectedFields[i].id] != undefined && this.selectedFields[i].value.length > 0){
console.info("Creating Parameter:" + this.selectedFields[i].id+" :"+this.selectedFields[i].value);
if(this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.selectedFields[i].id] != undefined && this.selectedFields[i].value != ""){
params +="&"+ this.selectedFields[i].id
+ "="+ this.selectedFields[i].value+"&"+this.searchFields.ADVANCED_FIELDS_NAMES_IDS[this.selectedFields[i].id].operator
+ "=" + this.selectedFields[i].operatorId;

View File

@ -19,15 +19,15 @@ export class AdvancedField{
public type: string = "keyword"; //keyword, static or dynamic
public value: string = '';
public operatorId: string;
public operatorName: string;;
public operatorName: string ="";
constructor(id:string,name:string, type:string, value:string){
constructor(id:string,name:string, type:string, value:string,operator:string){
this.id = id;
this.name = name;
this.type = type;
this.value = value;
this.operatorId = OPERATOR.AND;
this.operatorName = "AND";
this.operatorId = operator;
// this.operatorName = "AND";
}
}

View File

@ -4,19 +4,21 @@ import {Observable} from 'rxjs/Observable';
import {AutoCompleteValue} from '../searchPages/searchUtils/searchHelperClasses.class';
@Injectable()
export class ISVocabulariesService {
private api ="https://beta.services.openaire.eu/provision/mvc/vocabularies/";
constructor(private http: Http) {}
getVocabularyByType(type:string){
getVocabularyByType(type:string):AutoCompleteValue[]{
console.log("getVocabularyByType0"+ type);
if( type = "lang"){
return this.getLanguagesJsonFile();
}else if ( type == "type"){
return this.getPublicationTypesJsonFile();
}else if( type == "access"){
return this.getAccessModeJsonFile();
}
}
getLanguages ():any {
console.info("Get Languages from IS");
let url = "https://beta.services.openaire.eu/provision/mvc/vocabularies/dnet:languages.json";
let url = this.api+"dnet:languages.json";
return this.http.get(url)
.map(res => <any> res.json())
.map(res => res['terms'])
@ -24,16 +26,14 @@ export class ISVocabulariesService {
}
getLanguagesJsonFile ():any {
console.info("Get Languages from json");
var lang = JSON.parse(JSON.stringify(require('../utils/vocabularies/languages.json')));
getLanguagesJsonFile ():AutoCompleteValue[] {
var lang = JSON.parse(JSON.stringify(require('../utils/vocabularies/languages.json')));
return this.parse(lang["terms"]);
}
getPublicationTypes ():any {
console.info("Get Languages from IS");
let url = "https://beta.services.openaire.eu/provision/mvc/vocabularies/dnet:publication_resource.json";
let url = this.api+"dnet:publication_resource.json";
return this.http.get(url)
.map(res => <any> res.json())
.map(res => res['terms'])
@ -42,8 +42,47 @@ export class ISVocabulariesService {
}
getPublicationTypesJsonFile ():any {
console.info("Get Languages from json");
var lang = JSON.parse(JSON.stringify(require('../utils/vocabularies/publicationTypes.json')));
var lang = JSON.parse(JSON.stringify(require('../utils/vocabularies/publicationTypes.json')));
return this.parse(lang["terms"]);
}
getAccessMode ():any {
console.info("Get AccessMode from IS");
let url = this.api+"dnet:access_modes.json";
return this.http.get(url)
.map(res => <any> res.json())
.map(res => res['terms'])
.map(res => this.parse(res));
}
getAccessModeJsonFile ():any {
var lang = JSON.parse(JSON.stringify(require('../utils/vocabularies/accessMode.json')));
return this.parse(lang["terms"]);
}
getDataProviderTypes ():any {
let url = this.api+"dnet:datasource_typologies.json";
return this.http.get(url)
.map(res => <any> res.json())
.map(res => res['terms'])
.map(res => this.parse(res));
}
getDataProviderTypesJsonFile ():any {
var lang = JSON.parse(JSON.stringify(require('../utils/vocabularies/dataProviderType.json')));
return this.parse(lang["terms"]);
}
getDataProviderCompatibility ():any {
let url = this.api+"dnet:datasourceCompatibilityLevel.json";
return this.http.get(url)
.map(res => <any> res.json())
.map(res => res['terms'])
.map(res => this.parse(res));
}
getDataProviderCompatibilityJsonFile ():any {
var lang = JSON.parse(JSON.stringify(require('../utils/vocabularies/dataProviderCompatibility.json')));
return this.parse(lang["terms"]);
}

View File

@ -0,0 +1,49 @@
import {Injectable} from '@angular/core';
import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {AutoCompleteValue} from '../searchPages/searchUtils/searchHelperClasses.class';
import {OpenaireProperties} from '../utils/properties/openaireProperties';
@Injectable()
export class RefineFieldResultsService {
// scoobydoo.di.uoa.gr:8181/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2/api/projects?refine=true&fields=funderid&page=1&size=0
constructor(private http: Http) {}
getRefineFieldResultsByFieldName(fieldName:string, entityName:string):any{
let link = OpenaireProperties.getSearchAPIURLForEntity(entityName)+"?fields="+fieldName;
return this.getField(link,fieldName)
}
getField (link:string,fieldName:string):any{
let url = link+"&refine=true&page=1&size=0";
return this.http.get(url)
.map(res => <any> res.json())
.map(res => res['refineResults'])
// .do(res => console.info(res))
.map(res => this.parse(res,fieldName));
}
parse(data: any,fieldName:string):any {
var values:AutoCompleteValue[] = [];
if(data){
let field = data[fieldName];
for(let i=0; i<field.length; i++) {
var value:AutoCompleteValue = new AutoCompleteValue();
value.label = field[i].name;
value.id = field[i].id;
values.push(value);
}
}
return values;
}
private handleError (error: Response) {
// in a real world app, we may send the error to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);
return Observable.throw(error || 'Server error');
}
}

View File

@ -25,7 +25,7 @@ import {SearchProjectsService} from './searchProjects.service';
import {RefineResultsService} from './servicesUtils/refineResuts.service';
import {ISVocabulariesService} from './ISVocabularies.service';
import {RefineFieldResultsService} from './refineFieldResults.service'
@NgModule({
@ -40,7 +40,8 @@ import {ISVocabulariesService} from './ISVocabularies.service';
SearchCrossrefService, SearchDataciteService, SearchOrcidService,
SearchPublicationsService, SearchDataprovidersService, DataProviderService,
SearchProjectsService, SearchDatasetsService, SearchOrganizationsService,
SearchPeopleService,RefineResultsService, ISVocabulariesService
SearchPeopleService,RefineResultsService, ISVocabulariesService,
RefineFieldResultsService
],
exports: [
]

View File

@ -20,20 +20,22 @@ Selected::
<span >{{item.label}} </span>
</span>
<div style ="width:30%; height:250px;" >
<dynamic-autocomplete [(filtered)] =filteredObs [(selected)] =selectedObs [showSelected]=true
placeHolderMessage = "Search for Projects" title = "Projects:" [(searchTermStream)] = searchTermStream ></dynamic-autocomplete>
<div style ="width:80%; height:250px;" >
<dynamic-autocomplete [showSelected]=true
placeHolderMessage = "Search for Projects" title = "Projects:" ></dynamic-autocomplete>
<div>
`
//[(filtered)] =filteredObs [(selected)] =selectedObs
// [(searchTermStream)] = searchTermStream
//(keywordChange)="keywordChanged($event)"
})
export class TestComponent {
// for auto complete observable:
searchTermStream = new Subject<string>();
private selectedObs = [];
filteredObs: Observable<{}> = this.searchTermStream
.debounceTime(300).distinctUntilChanged()
.switchMap((term: string) => this.service(term));
// searchTermStream = new Subject<string>();
// private selectedObs = [];
// filteredObs: Observable<{}> = this.searchTermStream
// .debounceTime(300).distinctUntilChanged()
// .switchMap((term: string) => this.service(term));
private lan;
private types;
constructor(private _projectService: OpenaireProjectsService, private _vocabulariesService: ISVocabulariesService) {

View File

@ -6,6 +6,7 @@
.custom-autocomplete .suggestions,.custom-autocomplete .messages{
position:absolute;
z-index: 1000;
top: 25px;
}
.auto-complete-choice .remove {
cursor: pointer;
@ -24,10 +25,11 @@
border-radius:0;
border-color: white;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0) inset;
margin-left: 5px;
}
.form-control. auto-complete-input {
.form-control .auto-complete-input {
box-shadow: 0 1px 1px rgba(0, 0, 0, 0) inset;
}
.auto-complete-box .suggestions.list-group-item {
.auto-complete-box .suggestions .list-group-item, .custom-autocomplete .suggestions .list-group-item {
padding: 5px 10px;
}

View File

@ -10,32 +10,13 @@ import {OpenaireProjectsService} from '../services/openaireProjects.service';
@Component({
selector: 'dynamic-autocomplete',
// styles: [`
// .auto-complete-box{ }
// .auto-complete-choice .remove {
// cursor: pointer;
// }
// .auto-complete-choice{
// background: grey none repeat scroll 0 0;
// border-color: grey;
// border-radius: 5px;
// border-style: solid;
// color: white;
// margin: 3px;
// padding: 1px;
// }
// .auto-complete-input { border-radius:0; border-color: white; box-shadow: 0 1px 1px rgba(0, 0, 0, 0) inset; }
// .form-control. auto-complete-input {box-shadow: 0 1px 1px rgba(0, 0, 0, 0) inset;}
// .auto-complete-box .suggestions.list-group-item {
// padding: 5px 10px;
// }
// `],
styleUrls: ['autoComplete.component.css'],
template: `
<div class="bs-docs-grid">
<!--div class="bs-docs-grid">
<div class = "row-fluid form-inline auto-complete-box panel panel-default">
<div class="panel-heading">{{title}}</div>
<div class="panel-body">
<div class="panel-body"-->
<div class="custom-autocomplete">
<span *ngIf = "showSelected">
<span class="row-fluid show-grid auto-complete-choice" *ngFor="let item of selected" >
<span >{{showItem(item)}} </span>
@ -43,20 +24,23 @@ import {OpenaireProjectsService} from '../services/openaireProjects.service';
</span>
</span>
<input type="text" class="auto-complete-input validate filter-input input-sm form-control " [placeholder]=placeHolderMessage [(ngModel)]=keyword (keyup)=search() >
<div class="suggestions" *ngIf="filtered.length > 0">
<div class="suggestions" >
<ul class="list-group" >
<li class="list-group-item" *ngFor=" let item of filtered | async">
<a (click)="select(item)">{{showItem(item)}}</a>
</li>
</ul>
</div>
<div *ngIf="warningMessage.length > 0" class="alert alert-warning row-fluid " role="alert">{{warningMessage}}</div>
<div *ngIf="filtered.length == 0 && keyword.length >=3 " class="alert alert-info row-fluid " role="alert">No results Found</div>
<div class="messages">
<div *ngIf="warningMessage.length > 0" class="alert alert-warning row-fluid " role="alert">{{warningMessage}}</div>
<div *ngIf="filtered.length == 0 && keyword.length >=3 " class="alert alert-info row-fluid " role="alert">No results Found</div>
</div>
</div>
</div>
</div>
`
<!--/div>
</div>
</div-->
`
})
export class DynamicAutocompleteComponent {
@Input() placeHolderMessage = "Search for entries";
@ -66,14 +50,15 @@ export class DynamicAutocompleteComponent {
@Input() public showSelected = true; // the minimum length of keyword
@Input() public keyword = '';
@Input() public type = 'search' //search, result, context, project
@Output() keywordChange = new EventEmitter(); // when changed a method for filtering will be called
@Output() addNew = new EventEmitter(); // when changed a method for filtering will be called
// @Output() keywordChange = new EventEmitter(); // when changed a method for filtering will be called
// @Output() addNew = new EventEmitter(); // when changed a method for filtering will be called
// @Input() public selectedFunderId = "";
@Input() searchTermStream ; //= new Subject<string>();
@Input() filtered: Observable<{}> ;
// = this.searchTermStream
// .debounceTime(300).distinctUntilChanged()
// .switchMap((term: string) => this.service(term));// this._projectService.searchForProjectsObs(term, this.selectedFunderId));
@Input() searchTermStream = new Subject<string>();
@Input() filtered: Observable<{}> = this.searchTermStream
.debounceTime(300).distinctUntilChanged()
.switchMap((term: string) => this.service(term));
private warningMessage = "";
private infoMessage = "";
@ -83,14 +68,16 @@ export class DynamicAutocompleteComponent {
// this.elementRef = myElement;
}
// service(term) {
// var projects = this._projectService.searchForProjectsObs(term, this.selectedFunderId);
// console.info("Results: "+ projects);
// for( var i = 0 ; i<projects.length ; i++){
//
// }
// return projects;
// }
service(term) {
console.info("In service: "+ projects);
var projects = this._projectService.searchForProjectsObs(term, "");
console.info("Results: "+ projects);
for( var i = 0 ; i<projects.length ; i++){
}
return projects;
}
search() {
console.info("heeere "+this.keyword );
this.infoMessage = "";

View File

@ -107,6 +107,23 @@ export class OpenaireProperties {
public static getSearchAPIURL():string{
return this.searchAPIURL;
}
public static getSearchAPIURLForEntity(entityType:string):string{
var suffix = "";
if(entityType == "project"){
suffix="projects/";
}else if(entityType == "publication"){
suffix="publications/";
}else if(entityType == "dataset"){
suffix="datasets/";
}else if(entityType == "organization"){
suffix="organizations/";
}else if(entityType == "dataprovider"){
suffix="dataproviders/";
}else if(entityType == "person"){
suffix="peeople/";
}
return this.searchAPIURL + suffix;
}
public static getSearchServiceURL():string{
return this.searchServiveURL;
}

View File

@ -36,13 +36,34 @@ export class SearchFields {
public ADVANCED_FIELDS:string[] = ["instancetypenameid", "resultlanguageid", "communityid", "relfunderid",
"relfundinglevel0_id","relfundinglevel1_id,relfundinglevel2_id",
"resultacceptanceyear","resultbestlicense","resulthostingdatasourceid","collectedfromdatasourceid"];
public ADVANCED_SEARCH_PUBLICATIONS_FIELDS:string[] = ["all","title","author","publisher","type", "lan", "funder", "funderlv0",
"funderlv1","funderlv2"];
public ADVANCED_FIELDS_NAMES_IDS: { [key:string]:{ name:string, operator:string, type:string }} =
{["funder"]:{name:"Funder",operator:"fn", type:"keyword"},
["funderlv0"]:{name:"Funding Level 0",operator:"fn0", type:"keyword"},
["funderlv1"]:{name:"Funding Level 1",operator:"fn1", type:"keyword"}, ["funderlv2"]:{name:"Funding Level 2",operator:"fn2", type:"keyword"},
["type"]:{name:"Type",operator:"tp", type:"staticAutoComplete"},["lang"]: {name:"Language",operator:"ln", type:"staticAutoComplete"}};
public ADVANCED_SEARCH_PUBLICATIONS_FIELDS:string[] = ["q","title","author","publisher","type", "lang", "funder", "funderlv0",
"funderlv1","funderlv2","community","access","hostedBy","collectedFrom"];
public ADVANCED_FIELDS_NAMES_IDS: { [key:string]:{ name:string, operator:string, type:string, indexField:string }} ={
["q"]:{name:"All fields",operator:"op", type:"keyword", indexField:null},
["title"]:{name:"Title",operator:"tt", type:"keyword" , indexField:"resulttitle"},
["author"]:{name:"Author",operator:"at", type:"keyword", indexField:"relperson"},
["publisher"]:{name:"Publisher",operator:"pb", type:"keyword", indexField:"resultpublisher"},
["funder"]:{name:"Funder",operator:"fn", type:"refine", indexField:"relfunderid"},
["funderlv0"]:{name:"Funding Level 0",operator:"fn0", type:"refine", indexField:"relfundinglevel0_id"},
["funderlv1"]:{name:"Funding Level 1",operator:"fn1", type:"refine", indexField:"relfundinglevel1_id"},
["funderlv2"]:{name:"Funding Level 2",operator:"fn2", type:"refine", indexField:"relfundinglevel2_id"},
["type"]:{name:"Type",operator:"tp", type:"vocabulary", indexField:"instancetypenameid"},
["lang"]: {name:"Language",operator:"ln", type:"vocabulary", indexField:"resultlanguageid"},
["community"]: {name:"Community",operator:"cm", type:"refine", indexField:"communityid"},
["access"]: {name:"Access Mode",operator:"ac", type:"vocabulary", indexField:'resultbestlicense'},
["hostedBy"]: {name:"Hosted by data provider",operator:"hs", type:"refine", indexField:"resulthostingdatasourceid"},
["collectedFrom"]: {name:"Collected from data provider",operator:"cl", type:"refine", indexField:"collectedfromdatasourceid"}
};
public ADVANCED_SEARCH_OPERATORS:[{name:string, id:string}] = [{name:"AND",id:"and"},{name:"OR",id:"or"},{name:"NOT",id:"not"}];
// ,["communityid"]: "Context",["resultacceptanceyear"]:"Year",
// ["resultbestlicense"]:"Access Mode",["resulthostingdatasourceid"]:"Hosting Data provider",
// ["collectedfromdatasourceid"]:"Collected from", ["datasourcetypeuiid"]:"Compatibility Type", ["datasourceodlanguages"]:"Language",

View File

@ -1,7 +1,7 @@
import {Component, ElementRef, Input, Output, EventEmitter} from '@angular/core';
import {Value} from '../searchPages/searchUtils/searchHelperClasses.class';
import {ISVocabulariesService} from '../services/ISVocabularies.service';
import {RefineFieldResultsService} from '../services/refineFieldResults.service';
//Usage example
//<static-autocomplete [(filtered)] =filtered [(selected)] =selected placeHolderMessage = "Search for countries" title = "Countries:" (keywordChange)="keywordChanged($event)"></static-autocomplete>
@ -10,15 +10,18 @@ import {ISVocabulariesService} from '../services/ISVocabularies.service';
styleUrls: ['autoComplete.component.css'],
template: `
<div class="custom-autocomplete">
<span *ngIf = "showSelected">
<span class="row-fluid show-grid auto-complete-choice" *ngFor="let item of selected" >
<div *ngIf = "showSelected">
<div class="row-fluid show-grid auto-complete-choice" *ngFor="let item of selected" >
<span >{{showItem(item)}} </span>
<span (click)="remove(item)" aria-hidden="true" title="Remove selection" class=" remove glyphicon glyphicon-remove"></span>
</span>
</span>
</div>
</div>
<input *ngIf = "showInput" type="text" class="auto-complete-input validate filter-input input-sm form-control " [placeholder]=placeHolderMessage [(ngModel)]=keyword (keyup)=filter() >
<div class="suggestions" *ngIf="filtered.length > 0">
<ul class="list-group" >
<li class="list-group-item" >
Select:
</li>
<li class="list-group-item" *ngFor=" let item of filtered">
<a (click)="select(item)">{{showItem(item)}}</a>
</li>
@ -35,16 +38,17 @@ import {ISVocabulariesService} from '../services/ISVocabularies.service';
export class StaticAutocomplete2Component {
@Input() placeHolderMessage = "Search for entries";
@Input() title = "Autocomplete";
// @Output() keywordChange = new EventEmitter(); // when changed a method for filtering will be called
// @Output() addNew = new EventEmitter(); // when changed a method for filtering will be called
@Output() selectedValueChanged = new EventEmitter(); // when changed a method for filtering will be called
@Input() public list = []; // the entries resulted after filtering function
@Input() public filtered = []; // the entries resulted after filtering function
@Input() public selected = []; // the entries selected from user
@Input() public keywordlimit = 3; // the minimum length of keyword
@Input() public showSelected = true; // the minimum length of keyword
@Input() public multipleSelections:boolean = true;
@Input() public selectedId:string = '';
@Input() public vocabularyId:string = '';
@Input() public selectedValue:string = '';
@Input() public vocabularyId:string ;
@Input() public fieldName:string ;
@Input() public entityName:string ;
@Input() public keyword = '';
@Input() public type = 'search' //search, result, context, project
@ -54,33 +58,56 @@ export class StaticAutocomplete2Component {
private tries = 0;
private showInput = true;
constructor ( private _vocabulariesService: ISVocabulariesService) {
constructor ( private _vocabulariesService: ISVocabulariesService,private _refineService: RefineFieldResultsService) {
console.info("Type"+this.type);
}
ngOnInit () {
if(this.vocabularyId){
if(this.vocabularyId){
this.list = this._vocabulariesService.getVocabularyByType(this.vocabularyId);
this.getSelectedNameFromGivenId();
if(this.list.length == 0){
this.warningMessage = "There are no results"
}
}else if(this.fieldName && this.entityName){
console.info("Get From refine");
this.list = this._refineService.getRefineFieldResultsByFieldName(this.fieldName,this.entityName);
this._refineService.getRefineFieldResultsByFieldName(this.fieldName,this.entityName).subscribe(
data => {
this.list = data;
this.getSelectedNameFromGivenId();
if(this.list.length == 0 ){
this.warningMessage = "There are no results"
}
},
err => {
console.error(err);
this.warningMessage = "An Error occured..."
}
);
}
if(this.list.length == 0){
this.warningMessage = "There are no results"
}
}
filter() {
this.infoMessage = "";
this.filtered = [];
if(this.keyword == ""){
var cut = 5;
if(this.list.length < 5){
cut = this.list.length;
}
this.filtered =this.list.slice(0, cut);
this.tries = 0;
this.warningMessage = "";
} else if(this.keyword && this.keyword.length < this.keywordlimit){
this.tries++;
if(this.tries == this.keywordlimit -1 ){
this.warningMessage = "Type at least " + this.keywordlimit + " characters";
this.tries = 0;
}
// } else if(this.keyword && this.keyword.length < this.keywordlimit){
// this.tries++;
// if(this.tries == this.keywordlimit -1 ){
// this.warningMessage = "Type at least " + this.keywordlimit + " characters";
// this.tries = 0;
// }
}else{
this.tries = 0;
this.warningMessage = "";
console.log("keyword Changed"+this.list.length+" "+this.list[0].id+"-"+this.list[0].label);
this.filtered = this.list.filter(function(el){
return el.label.toLowerCase().indexOf(this.keyword.toLowerCase()) > -1;
}.bind(this));
@ -94,7 +121,10 @@ export class StaticAutocomplete2Component {
}
if(!this.multipleSelections && this.selected.length == 0 ){
this.showInput = true;
this.selectedId = "";
this.selectedValue = "";
this.selectedValueChanged.emit({
value: this.selectedValue
});
}
}
select(item:any){
@ -116,7 +146,10 @@ export class StaticAutocomplete2Component {
this.filtered.splice(0, this.filtered.length);
this.keyword = "";
this.showInput = false;
this.selectedId = item.id;
this.selectedValue = item.id;
this.selectedValueChanged.emit({
value: this.selectedValue
});
}
}
@ -153,7 +186,15 @@ export class StaticAutocomplete2Component {
}
}
private getSelectedNameFromGivenId(){
for( var i = 0; i < this.list.length; i++){
if(this.list[i].id == this.selectedValue){
this.selectedValue = this.list[i].label;
this.selected.push(this.list[i]);
this.showInput = false;
}
}
}
// handleClick(event){
// var clickedComponent = event.target;

View File

@ -0,0 +1 @@
{"id":"344de4f6-8d27-4382-a3d5-5bcd3bf2c33e_Vm9jYWJ1bGFyeURTUmVzb3VyY2VzL1ZvY2FidWxhcnlEU1Jlc291cmNlVHlwZQ==","name":"dnet:access_modes","description":"dnet:access_modes","code":"dnet:access_modes","terms":[{"englishName":"12 Months Embargo","nativeName":"12 Months Embargo","encoding":"OPENAIRE","code":"12MONTHS"},{"englishName":"6 Months Embargo","nativeName":"6 Months Embargo","encoding":"OPENAIRE","code":"6MONTHS"},{"englishName":"Closed Access","nativeName":"Closed Access","encoding":"OPENAIRE","code":"CLOSED"},{"englishName":"Embargo","nativeName":"Embargo","encoding":"OPENAIRE","code":"EMBARGO"},{"englishName":"Open Access","nativeName":"Open Access","encoding":"OPENAIRE","code":"OPEN"},{"englishName":"Other","nativeName":"Other","encoding":"OPENAIRE","code":"OTHER"},{"englishName":"Restricted","nativeName":"Restricted","encoding":"OPENAIRE","code":"RESTRICTED"},{"englishName":"not available","nativeName":"UNKNOWN","encoding":"OPENAIRE","code":"UNKNOWN"}]}

View File

@ -0,0 +1 @@
{"id":"da6b3e2f-2a05-4975-85f8-e66aaa8cb93e_Vm9jYWJ1bGFyeURTUmVzb3VyY2VzL1ZvY2FidWxhcnlEU1Jlc291cmNlVHlwZQ==","name":"dnet:datasourceCompatibilityLevel","description":"dnet:datasourceCompatibilityLevel","code":"dnet:datasourceCompatibilityLevel","terms":[{"englishName":"OpenAIRE 2.0 (EC funding)","nativeName":"OpenAIRE 2.0 (EC funding)","encoding":"OPENAIRE","code":"openaire2.0"},{"englishName":"OpenAIRE 2.0+ (DRIVER OA, EC funding)","nativeName":"OpenAIRE 2.0+ (DRIVER OA, EC funding)","encoding":"OPENAIRE","code":"driver-openaire2.0"},{"englishName":"OpenAIRE 3.0 (OA, funding)","nativeName":"OpenAIRE 3.0 (OA, funding)","encoding":"OPENAIRE","code":"openaire3.0"},{"englishName":"OpenAIRE Basic (DRIVER OA)","nativeName":"OpenAIRE basic (DRIVER OA)","encoding":"OPENAIRE","code":"driver"},{"englishName":"OpenAIRE Data (funded, referenced datasets)","nativeName":"OpenAIRE Data (funded, referenced datasets)","encoding":"OPENAIRE","code":"openaire2.0_data"},{"englishName":"collected from a compatible aggregator","nativeName":"collected from a compatible aggregator","encoding":"OPENAIRE","code":"hostedBy"},{"englishName":"not available","nativeName":"not available","encoding":"OPENAIRE","code":"UNKNOWN"},{"englishName":"proprietary","nativeName":"native","encoding":"OPENAIRE","code":"native"},{"englishName":"under validation","nativeName":"under validation","encoding":"OPENAIRE","code":"notCompatible"}]}

View File

@ -0,0 +1 @@
{"id":"51b3a0ad-7054-4b3b-acbc-b3c9657f113c_Vm9jYWJ1bGFyeURTUmVzb3VyY2VzL1ZvY2FidWxhcnlEU1Jlc291cmNlVHlwZQ==","name":"dnet:datasource_typologies","description":"dnet:datasource_typologies","code":"dnet:datasource_typologies","terms":[{"englishName":"CRIS System","nativeName":"CRIS System","encoding":"OPENAIRE","code":"crissystem"},{"englishName":"Data Repository","nativeName":"Data Repository","encoding":"OPENAIRE","code":"datarepository::unknown"},{"englishName":"Data Repository Aggregator","nativeName":"Data Repository Aggregator","encoding":"OPENAIRE","code":"aggregator::datarepository"},{"englishName":"Funder database","nativeName":"Funder database","encoding":"OPENAIRE","code":"entityregistry::projects"},{"englishName":"Information Space","nativeName":"Information Space","encoding":"OPENAIRE","code":"infospace"},{"englishName":"Institutional Repository","nativeName":"Institutional Repository","encoding":"OPENAIRE","code":"pubsrepository::institutional"},{"englishName":"Institutional Repository Aggregator","nativeName":"Institutional Repository Aggregator","encoding":"OPENAIRE","code":"aggregator::pubsrepository::institutional"},{"englishName":"Journal","nativeName":"Journal","encoding":"OPENAIRE","code":"pubsrepository::journal"},{"englishName":"Journal Aggregator/Publisher","nativeName":"Journal Aggregator/Publisher","encoding":"OPENAIRE","code":"aggregator::pubsrepository::journals"},{"englishName":"Other","nativeName":"Other","encoding":"OPENAIRE","code":"pubsrepository::mock"},{"englishName":"Publication Catalogue","nativeName":"Publication Catalogue","encoding":"OPENAIRE","code":"pubscatalogue::unknown"},{"englishName":"Publication Repository","nativeName":"Publication Repository","encoding":"OPENAIRE","code":"pubsrepository::unknown"},{"englishName":"Publication Repository Aggregator","nativeName":"Publication Repository Aggregator","encoding":"OPENAIRE","code":"aggregator::pubsrepository::unknown"},{"englishName":"Registry","nativeName":"Registry","encoding":"OPENAIRE","code":"entityregistry"},{"englishName":"Registry of repositories","nativeName":"Registry of repositories","encoding":"OPENAIRE","code":"entityregistry::repositories"},{"englishName":"Scholarly Comm. Infrastructure","nativeName":"Scholarly Comm. Infrastructure","encoding":"OPENAIRE","code":"scholarcomminfra"},{"englishName":"Thematic Repository","nativeName":"Thematic Repository","encoding":"OPENAIRE","code":"pubsrepository::thematic"},{"englishName":"Web Source","nativeName":"Web Source","encoding":"OPENAIRE","code":"websource"}]}