2019-04-08 16:56:09 +02:00
import { Component , ElementRef , ViewChild } from "@angular/core" ;
2019-04-05 19:29:28 +02:00
import { SearchUtilsClass } from "../../openaireLibrary/searchPages/searchUtils/searchUtils.class" ;
import { ErrorMessagesComponent } from "../../openaireLibrary/utils/errorMessages.component" ;
import { ErrorCodes } from "../../openaireLibrary/utils/properties/errorCodes" ;
import { EnvProperties } from "../../openaireLibrary/utils/properties/env-properties" ;
import { SearchPageComponent } from "../../openaireLibrary/searchPages/searchUtils/searchPage.component" ;
import { ActivatedRoute } from "@angular/router" ;
import { Filter , Value } from "../../openaireLibrary/searchPages/searchUtils/searchHelperClasses.class" ;
import { SearchFields } from "../../openaireLibrary/utils/properties/searchFields" ;
import { CommunitiesService } from "../../openaireLibrary/connect/communities/communities.service" ;
import { Session } from "../../openaireLibrary/login/utils/helper.class" ;
import { CommunityInfo } from "../../openaireLibrary/connect/community/communityInfo" ;
import { SearchResult } from "../../openaireLibrary/utils/entities/searchResult" ;
import { SubscribeService } from "../../openaireLibrary/utils/subscribe/subscribe.service" ;
import { Observable } from "rxjs" ;
import { StringUtils } from "../../openaireLibrary/utils/string-utils.class" ;
2019-04-12 11:50:10 +02:00
import { PiwikService } from "../../openaireLibrary/utils/piwik/piwik.service" ;
2019-04-05 19:29:28 +02:00
@Component ( {
selector : 'search-communities' ,
template : `
2019-04-12 11:50:10 +02:00
< search - page pageTitle = "OpenAIRE Connect|Search Communities"
2019-04-05 19:29:28 +02:00
formPlaceholderText = "Search for Research Communities and Initiatives"
2019-04-12 16:16:08 +02:00
type = "communities" entityType = "community" [ filters ] = "filters"
2019-04-05 19:29:28 +02:00
[ results ] = "results" [ searchUtils ] = "searchUtils"
[ showResultCount ] = true [ baseUrl ] = "baseUrl"
( queryChange ) = "queryChanged($event)"
[ disableForms ] = "disableForms"
[ lastIndex ] = false [ sort ] = true
searchFormClass = "communitiesSearchForm" >
< / s e a r c h - p a g e >
`
} )
export class SearchCommunitiesComponent {
2019-04-12 11:50:10 +02:00
public piwiksub : any ;
2019-04-05 19:29:28 +02:00
private errorCodes : ErrorCodes ;
private errorMessages : ErrorMessagesComponent ;
2019-04-13 20:21:51 +02:00
public results : CommunityInfo [ ] = [ ] ;
public totalResults : CommunityInfo [ ] = [ ] ;
2019-04-05 19:29:28 +02:00
public sub : any ; public subResults : any ;
public filters = [ ] ;
public searchFields :SearchFields = new SearchFields ( ) ;
public searchUtils :SearchUtilsClass = new SearchUtilsClass ( ) ;
public disableForms : boolean = false ;
public baseUrl : string = null ;
public refineFields : string [ ] = this . searchFields . COMMUNITIES_SEARCH_FIELDS ;
properties :EnvProperties ;
@ViewChild ( SearchPageComponent ) searchPage : SearchPageComponent ;
2019-04-08 16:56:09 +02:00
constructor ( private route : ActivatedRoute ,
private _communitiesService : CommunitiesService ,
private _subscribeService : SubscribeService ,
2019-04-12 11:50:10 +02:00
private element : ElementRef ,
2019-04-12 13:54:49 +02:00
private _piwikService : PiwikService ) {
2019-04-05 19:29:28 +02:00
this . errorCodes = new ErrorCodes ( ) ;
this . errorMessages = new ErrorMessagesComponent ( ) ;
this . searchUtils . status = this . errorCodes . LOADING ;
}
public ngOnInit() {
this . route . data
. subscribe ( ( data : { envSpecific : EnvProperties } ) = > {
this . properties = data . envSpecific ;
this . baseUrl = data . envSpecific . searchLinkToCommunities ;
2019-04-12 11:50:10 +02:00
if ( this . properties . enablePiwikTrack && ( typeof document !== 'undefined' ) ) {
this . piwiksub = this . _piwikService . trackView ( this . properties , "OpenAIRE Connect|Search Communities" , this . properties . piwikSiteId ) . subscribe ( ) ;
}
2019-04-05 19:29:28 +02:00
} ) ;
this . sub = this . route . queryParams . subscribe ( params = > {
2019-04-07 18:08:10 +02:00
this . searchPage . resultsPerPage = 5 ;
2019-04-05 19:29:28 +02:00
this . searchUtils . keyword = ( params [ 'keyword' ] ? params [ 'keyword' ] : '' ) ;
this . searchUtils . page = ( params [ 'page' ] === undefined ) ? 1 : + params [ 'page' ] ;
2019-04-07 18:08:10 +02:00
this . searchUtils . sortBy = ( params [ 'sortBy' ] === undefined ) ? '' : params [ 'sortBy' ] ;
2019-04-05 19:29:28 +02:00
this . searchUtils . size = ( params [ 'size' ] === undefined ) ? this . searchPage . resultsPerPage : + params [ 'size' ] ;
2019-04-07 18:08:10 +02:00
if ( this . searchUtils . size != 5 && this . searchUtils . size != 10 && this . searchUtils . size != 20 && this . searchUtils . size != 50 ) {
this . searchUtils . size = this . searchPage . resultsPerPage ;
}
if ( this . searchUtils . sortBy && this . searchUtils . sortBy != "creationdate,descending" && this . searchUtils . sortBy != "creationdate,ascending" ) {
this . searchUtils . sortBy = "" ;
}
2019-04-05 19:29:28 +02:00
this . searchPage . refineFields = this . refineFields ;
let queryParams = this . searchPage . getQueryParamsFromUrl ( params ) ;
this . filters = this . createFilters ( ) ;
2019-04-13 20:21:51 +02:00
this . initCommunities ( queryParams ) ;
2019-04-05 19:29:28 +02:00
} ) ;
}
public ngOnDestroy() {
if ( this . sub ) {
this . sub . unsubscribe ( ) ;
}
if ( this . subResults ) {
this . subResults . unsubscribe ( ) ;
}
}
2019-04-12 11:50:10 +02:00
/ * *
2019-04-13 20:21:51 +02:00
* Initialize communities from Communities APIs
2019-04-12 11:50:10 +02:00
*
* @param params
* /
2019-04-13 20:21:51 +02:00
private initCommunities ( params : Map < string , string > ) {
2019-04-05 19:29:28 +02:00
this . subResults = this . _communitiesService . getCommunities ( this . properties , this . properties . communitiesAPI ) . subscribe (
data = > {
let observables : Observable < boolean > [ ] = [ ] ;
for ( let i = 0 ; i < data . length ; i ++ ) {
2019-04-13 20:21:51 +02:00
this . totalResults [ i ] = data [ i ] ;
2019-04-08 16:56:09 +02:00
// For Test do not delete them.
2019-04-13 20:21:51 +02:00
//this.results[i].description = "EGI is a federated e-Infrastructure set up to provide advanced computing services for research and innovation.EGI is a federated e-Infrastructure set up to provide advanced computing services for research and innovation.EGI is a federated e-Infrastructure set up to provide advanced computing services for research and innovation."
//this.results[i].date = new Date(new Date(2012, 0, 1).getTime() + Math.random() * (new Date().getTime() - new Date(2012, 0, 1).getTime()));
observables . push ( this . _subscribeService . isSubscribedToCommunity ( this . totalResults [ i ] . communityId , Session . getUserEmail ( ) , this . properties [ "adminToolsAPIURL" ] ) ) ;
this . totalResults [ i ] . isManager = this . isCommunityManager ( this . results [ i ] ) ;
2019-04-05 19:29:28 +02:00
}
Observable . forkJoin ( observables ) . subscribe (
res = > {
for ( let i = 0 ; i < res . length ; i ++ ) {
2019-04-13 20:21:51 +02:00
this . totalResults [ i ] . isSubscribed = res [ i ] ;
2019-04-05 19:29:28 +02:00
}
2019-04-13 20:21:51 +02:00
this . _getResults ( params , this . errorCodes . DONE ) ;
2019-04-05 19:29:28 +02:00
} ,
err = > {
this . handleError ( 'Error getting if user is subscribed' , err ) ;
2019-04-13 20:21:51 +02:00
this . _getResults ( params , this . errorCodes . MISSING_CONTENT ) ;
2019-04-05 19:29:28 +02:00
}
) ;
} ,
err = > {
//console.log(err);
this . handleError ( 'Error getting communities' , err ) ;
this . searchUtils . status = this . errorMessages . getErrorCode ( err . status ) ;
this . disableForms = false ;
2019-04-08 16:56:09 +02:00
this . scroll ( ) ;
2019-04-05 19:29:28 +02:00
}
) ;
}
2019-04-13 20:21:51 +02:00
/ * *
* Get all communities from Communities API and apply permission access validator ,
* keyword searching , filter , paging and sorting .
*
* @param params , status
* @private
* /
private _getResults ( params : Map < string , string > , status : number ) {
this . searchUtils . status = this . errorCodes . LOADING ;
this . disableForms = true ;
this . results = this . totalResults ;
this . searchUtils . totalResults = 0 ;
this . applyParams ( params , status ) ;
}
/ * *
* Return the communities in which user has permission to view or manage .
* /
private showCommunities() {
let ret : CommunityInfo [ ] = [ ] ;
for ( let result of this . results ) {
if ( result . status == 'hidden' ) {
continue ;
} else if ( result . status == "manager" ) {
let mail = Session . getUserEmail ( ) ;
if ( mail == null ) { // no user
continue ;
} else if ( Session . isCommunityCurator ( ) || Session . isPortalAdministrator ( ) ) {
ret . push ( result ) ;
} else if ( result . managers . indexOf ( mail ) != - 1 ) {
ret . push ( result ) ;
}
continue ;
}
ret . push ( result ) ;
}
this . results = ret ;
}
2019-04-12 16:16:08 +02:00
/ * *
* Apply permission access validator ,
* keyword searching , filter , paging and sorting .
*
* @param params
* @param status
* /
public applyParams ( params : Map < string , string > , status : number ) {
this . showCommunities ( ) ;
if ( this . searchUtils . keyword && this . searchUtils . keyword != '' ) {
this . searchForKeywords ( ) ;
}
this . checkFilters ( params ) ;
this . sort ( ) ;
this . searchUtils . totalResults = this . results . length ;
this . searchPage . checkSelectedFilters ( this . filters ) ;
this . searchPage . updateBaseUrlWithParameters ( this . filters ) ;
this . results = this . results . slice ( ( this . searchUtils . page - 1 ) * this . searchUtils . size , ( this . searchUtils . page * this . searchUtils . size ) ) ;
this . searchUtils . status = status ;
if ( this . searchUtils . totalResults == 0 ) {
this . searchUtils . status = this . errorCodes . NONE ;
}
else if ( this . searchUtils . totalResults == 1 ) {
this . searchPage . type = this . searchPage . entityType ;
}
this . disableForms = false ;
if ( this . searchUtils . status == status ) {
// Page out of limit!!!
let totalPages :any = this . searchUtils . totalResults / ( this . searchUtils . size ) ;
if ( ! ( Number . isInteger ( totalPages ) ) ) {
totalPages = ( parseInt ( totalPages , 10 ) + 1 ) ;
}
if ( totalPages < this . searchUtils . page ) {
this . searchUtils . totalResults = 0 ;
this . searchUtils . status = this . errorCodes . OUT_OF_BOUND ;
}
}
this . scroll ( ) ;
}
2019-04-12 11:50:10 +02:00
/ * *
* Parse the given keywords into array and check if any of the requirements field of a community includes
* one of the given words .
* /
2019-04-07 18:08:10 +02:00
private searchForKeywords() {
2019-04-13 20:21:51 +02:00
let ret : CommunityInfo [ ] = [ ] ;
2019-04-07 18:08:10 +02:00
let keywords : string [ ] = this . searchUtils . keyword . split ( /,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/ , - 1 ) ;
for ( let i = 0 ; i < this . results . length ; i ++ ) {
for ( let keyword of keywords ) {
2019-04-13 20:21:51 +02:00
if ( keyword != '' && ( this . results [ i ] . title . includes ( keyword ) || this . results [ i ] . shortTitle . includes ( keyword ) ||
this . results [ i ] . communityId . includes ( keyword ) || this . results [ i ] . description . includes ( keyword ) ) ) {
2019-04-07 18:08:10 +02:00
ret . push ( this . results [ i ] ) ;
break ;
}
}
}
this . results = ret ;
}
2019-04-12 11:50:10 +02:00
/ * *
* Check the current results if they satisfy the values of each filter category and
* update the number of possible results in each value .
*
* @param params
* /
2019-04-05 19:29:28 +02:00
private checkFilters ( params : Map < string , string > ) {
2019-04-13 20:21:51 +02:00
let typeResults : CommunityInfo [ ] = this . applyFilter ( 'type' , params ) ;
let statusResults : CommunityInfo [ ] = this . applyFilter ( 'status' , params ) ;
let roleResults : CommunityInfo [ ] = this . applyFilter ( 'role' , params ) ;
2019-04-12 10:54:55 +02:00
this . resetFilterNumbers ( 'status' ) ;
this . updateFilterNumbers ( typeResults . filter ( value = > {
return roleResults . includes ( value ) ;
} ) , 'status' ) ;
2019-04-07 18:08:10 +02:00
this . resetFilterNumbers ( 'type' ) ;
2019-04-12 10:54:55 +02:00
this . updateFilterNumbers ( statusResults . filter ( value = > {
return roleResults . includes ( value ) ;
} ) , 'type' ) ;
this . resetFilterNumbers ( 'role' ) ;
this . updateFilterNumbers ( statusResults . filter ( value = > {
return typeResults . includes ( value ) ;
} ) , 'role' ) ;
2019-04-07 18:08:10 +02:00
this . results = statusResults . filter ( value = > {
return typeResults . includes ( value ) ;
2019-04-12 10:54:55 +02:00
} )
this . results = this . results . filter ( value = > {
return roleResults . includes ( value ) ;
2019-04-07 18:08:10 +02:00
} ) ;
2019-04-05 19:29:28 +02:00
}
2019-04-12 11:50:10 +02:00
/ * *
* Apply filter with filterId and return the results
*
* @param filterId
* @param params
* /
2019-04-13 20:21:51 +02:00
private applyFilter ( filterId : string , params : Map < string , string > ) : CommunityInfo [ ] {
let results :CommunityInfo [ ] = [ ] ;
2019-04-12 11:50:10 +02:00
let values : string [ ] = [ ] ;
if ( params . get ( filterId ) != undefined ) {
values = ( StringUtils . URIDecode ( params . get ( filterId ) ) ) . split ( /,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/ , - 1 ) ;
}
if ( filterId == 'type' ) {
for ( let i = 0 ; i < this . results . length ; i ++ ) {
if ( values . length == 0 ) {
results . push ( this . results [ i ] ) ;
} else {
for ( let value of values ) {
2019-04-13 20:21:51 +02:00
if ( this . results [ i ] . type == value . replace ( /["']/g , "" ) ) {
2019-04-12 11:50:10 +02:00
results . push ( this . results [ i ] ) ;
break ;
}
}
}
}
}
else if ( filterId == 'status' ) {
for ( let i = 0 ; i < this . results . length ; i ++ ) {
if ( values . length == 0 ) {
results . push ( this . results [ i ] ) ;
} else {
for ( let value of values ) {
if ( value . replace ( /["']/g , "" ) == 'subscribed' ) {
if ( this . results [ i ] . isSubscribed ) {
results . push ( this . results [ i ] ) ;
break ;
}
} else if ( value . replace ( /["']/g , "" ) == 'nonsubscribed' ) {
if ( ! this . results [ i ] . isSubscribed ) {
results . push ( this . results [ i ] ) ;
break ;
}
}
}
}
}
}
else if ( filterId == 'role' ) {
for ( let i = 0 ; i < this . results . length ; i ++ ) {
if ( values . length == 0 ) {
results . push ( this . results [ i ] ) ;
} else {
for ( let value of values ) {
if ( value . replace ( /["']/g , "" ) == 'manager' ) {
if ( this . results [ i ] . isManager ) {
results . push ( this . results [ i ] ) ;
break ;
}
}
}
}
}
}
return results ;
}
2019-04-07 18:08:10 +02:00
/ * *
* Reset the values of filter with id filterId with zero .
*
* @param filterId
* /
private resetFilterNumbers ( filterId : string ) {
2019-04-05 19:29:28 +02:00
for ( let i = 0 ; i < this . filters . length ; i ++ ) {
2019-04-07 18:08:10 +02:00
if ( this . filters [ i ] . filterId == filterId ) {
for ( let j = 0 ; j < this . filters [ i ] . values . length ; j ++ ) {
this . filters [ i ] . values [ j ] . number = 0 ;
}
break ;
2019-04-05 19:29:28 +02:00
}
}
2019-04-07 18:08:10 +02:00
}
/ * *
* Update the values of filter with id filterId based on
* results .
*
* @param results
* @param filterId
* /
2019-04-13 20:21:51 +02:00
private updateFilterNumbers ( results : CommunityInfo [ ] , filterId : string ) {
2019-04-05 19:29:28 +02:00
for ( let k = 0 ; k < results . length ; k ++ ) {
for ( let i = 0 ; i < this . filters . length ; i ++ ) {
2019-04-07 18:08:10 +02:00
if ( this . filters [ i ] . filterId == filterId ) {
if ( this . filters [ i ] . filterId == 'type' ) {
for ( let j = 0 ; j < this . filters [ i ] . values . length ; j ++ ) {
2019-04-13 20:21:51 +02:00
if ( results [ k ] . type == this . filters [ i ] . values [ j ] . id ) {
2019-04-07 18:08:10 +02:00
this . filters [ i ] . values [ j ] . number ++ ;
}
}
2019-04-05 19:29:28 +02:00
}
2019-04-07 18:08:10 +02:00
if ( this . filters [ i ] . filterId == 'status' ) {
if ( results [ k ] . isSubscribed ) {
this . filters [ i ] . values [ 0 ] . number ++ ;
} else {
this . filters [ i ] . values [ 1 ] . number ++ ;
}
2019-04-12 10:54:55 +02:00
}
if ( this . filters [ i ] . filterId == 'role' ) {
2019-04-07 18:08:10 +02:00
if ( results [ k ] . isManager ) {
2019-04-12 10:54:55 +02:00
this . filters [ i ] . values [ 0 ] . number ++ ;
2019-04-07 18:08:10 +02:00
}
}
break ;
2019-04-05 19:29:28 +02:00
}
}
}
}
2019-04-07 18:08:10 +02:00
/ * *
* Sorting results based on sortBy .
* /
private sort() {
if ( this . searchUtils . sortBy == '' ) {
this . results . sort ( ( left , right ) : number = > {
2019-04-13 20:21:51 +02:00
if ( left . title > right . title ) {
2019-04-07 18:08:10 +02:00
return 1 ;
2019-04-13 20:21:51 +02:00
} else if ( left . title < right . title ) {
2019-04-07 18:08:10 +02:00
return - 1 ;
} else {
return 0 ;
}
} )
} else if ( this . searchUtils . sortBy == 'creationdate,descending' ) {
this . results . sort ( ( left , right ) : number = > {
2019-04-13 20:21:51 +02:00
if ( ! right . date || left . date > right . date ) {
2019-04-07 18:08:10 +02:00
return - 1 ;
2019-04-13 20:21:51 +02:00
} else if ( ! left . date || left . date < right . date ) {
2019-04-07 18:08:10 +02:00
return 1 ;
} else {
return 0 ;
}
} )
} else if ( this . searchUtils . sortBy == 'creationdate,ascending' ) {
this . results . sort ( ( left , right ) : number = > {
2019-04-13 20:21:51 +02:00
if ( ! right . date || left . date > right . date ) {
2019-04-07 18:08:10 +02:00
return 1 ;
2019-04-13 20:21:51 +02:00
} else if ( ! left . date || left . date < right . date ) {
2019-04-07 18:08:10 +02:00
return - 1 ;
} else {
return 0 ;
}
} )
}
}
2019-04-05 19:29:28 +02:00
private isCommunityManager ( community : CommunityInfo ) : boolean {
return Session . isCommunityCurator ( ) || community . managers . indexOf ( Session . getUserEmail ( ) ) != - 1 ;
}
public queryChanged ( $event ) {
2019-04-13 20:21:51 +02:00
this . _getResults ( $event . params , this . errorCodes . DONE ) ;
2019-04-05 19:29:28 +02:00
}
2019-04-07 18:08:10 +02:00
/ * *
* Create Search Communities filters .
*
* /
2019-04-05 19:29:28 +02:00
private createFilters ( ) : Filter [ ] {
let filter_names = [ "Type" ] ;
let filter_ids = [ "type" ] ;
let searchFields = new SearchFields ( ) ;
let filter_original_ids = searchFields . COMMUNITIES_SEARCH_FIELDS ;
let value_names = [
[ "Research Communities" , "Research Initiatives" ]
] ;
let value_original_ids = [
[ "community" , "ri" ]
] ;
if ( Session . isLoggedIn ( ) ) {
filter_names [ 1 ] = "Status" ;
filter_ids [ 1 ] = "status" ;
2019-04-12 10:54:55 +02:00
value_names [ 1 ] = [ "Subscribed" , "Non-subscribed" ] ;
value_original_ids [ 1 ] = [ "subscribed" , "nonsubscribed" ] ;
filter_names [ 2 ] = "Role" ;
filter_ids [ 2 ] = "role" ;
value_names [ 2 ] = [ "Manager" ] ;
value_original_ids [ 2 ] = [ "manager" ] ;
2019-04-05 19:29:28 +02:00
}
let filters : Filter [ ] = [ ] ;
for ( let i = 0 ; i < filter_names . length ; i ++ ) {
let values : Value [ ] = [ ] ;
for ( let j = 0 ; j < value_names [ i ] . length ; j ++ ) {
2019-04-07 18:08:10 +02:00
let value : Value = { name : value_names [ i ] [ j ] , id : value_original_ids [ i ] [ j ] , number : 0 , selected :false } ;
2019-04-05 19:29:28 +02:00
values . push ( value ) ;
}
let filter : Filter = { title : filter_names [ i ] , filterId : filter_ids [ i ] , originalFilterId : filter_original_ids [ i ] , values : values , countSelectedValues :0 , "filterOperator" : 'or' , valueIsExact : true } ;
filters . push ( filter ) ;
}
return filters ;
}
private handleError ( message : string , error ) {
console . error ( 'Communities Search Page: ' + message , error ) ;
}
2019-04-08 16:56:09 +02:00
public scroll() {
if ( typeof document !== 'undefined' ) {
this . element . nativeElement . scrollIntoView ( ) ;
}
}
2019-04-05 19:29:28 +02:00
}