commit 86e750754b3731e7a32e55369868282d1df631f9 Author: argiro.kokogiannaki Date: Tue Dec 19 12:53:46 2017 +0000 Commiting first draft of openaire library for angular portals git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-services-library/trunk/ng-openaire-library/src/app@50169 d315682c-612b-4755-9ff5-7f18f6832af3 diff --git a/app.component.ts b/app.component.ts new file mode 100644 index 00000000..fe237168 --- /dev/null +++ b/app.component.ts @@ -0,0 +1,56 @@ +import { Component, Directive, ElementRef, Renderer, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { ConfigurationService } from './utils/configuration/configuration.service'; +import {Observable} from 'rxjs/Observable'; + +@Component({ + //changeDetection: ChangeDetectionStrategy.Default, + //encapsulation: ViewEncapsulation.Emulated, + selector: 'app-root', + styles: [` + `], + template: ` +

Openaire Lib Component

+ + + + +
+
+ + +
+
+ + + +` + +}) +export class AppComponent { + isClient:boolean = false; + constructor(private config: ConfigurationService) {} + + ngOnInit() { + + if (typeof document !== 'undefined') { + try{ + this.isClient = true; + }catch (e) { + } + } + } +} diff --git a/app.module.ts b/app.module.ts new file mode 100755 index 00000000..d76a6f30 --- /dev/null +++ b/app.module.ts @@ -0,0 +1,145 @@ +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { SharedModule } from './shared/shared.module'; +import { BrowserModule } from '@angular/platform-browser'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { APP_BASE_HREF, CommonModule } from '@angular/common'; +import { HttpModule } from '@angular/http'; +import { RouterModule } from '@angular/router'; +import { AppComponent } from './app.component'; +import {SharedComponentsModule} from './sharedComponents/sharedComponents.module'; //navbar +import { CookieLawModule } from './sharedComponents/cookie-law/cookie-law.module'; +import {Meta} from '../angular2-meta'; +// import { ErrorModule } from './error/error.module'; +import { ConfigurationService } from './utils/configuration/configuration.service'; +import { ErrorPageComponent } from './error/errorPage.component'; +import {SearchComponent} from './searchPages/find/search.component'; +import {MainSearchModule} from './searchPages/find/mainSearch.module'; +import {PublicationComponent} from './landingPages/publication/publication.component'; +import {PublicationModule} from './landingPages/publication/publication.module'; +import {DatasetComponent} from './landingPages/dataset/dataset.component'; +import {DatasetModule} from './landingPages/dataset/dataset.module'; +import {SoftwareComponent} from './landingPages/software/software.component'; +import {SoftwareModule} from './landingPages/software/software.module'; +import {DataProviderComponent} from './landingPages/dataProvider/dataProvider.component'; +import {DataProviderModule} from './landingPages/dataProvider/dataProvider.module'; +import {ProjectComponent} from './landingPages/project/project.component'; +import {ProjectModule} from './landingPages/project/project.module'; +import {OrganizationComponent} from './landingPages/organization/organization.component'; +import {OrganizationModule} from './landingPages/organization/organization.module'; +import {ReloadModule} from './reload/reload.module'; +import {ErrorModule} from './error/error.module'; +import {DepositDatasetsModule} from './deposit/datasets/depositDatasets.module'; +import {DepositDatasetsComponent} from './deposit/datasets/depositDatasets.component'; +import {DepositDatasetsResultsModule} from './deposit/datasets/depositDatasetsResults.module'; +import {DepositDatasetsResultComponent} from './deposit/datasets/depositDatasetsResult.component'; +import {DepositBySubjectResultsModule} from './deposit/datasets/depositBySubjectResults.module'; +import {DepositBySubjectResultComponent} from './deposit/datasets/depositBySubjectResult.component'; +import {DepositPublicationsModule} from './deposit/publications/depositPublications.module'; +import {DepositPublicationsComponent} from './deposit/publications/depositPublications.component'; +import {DepositPublicationsResultsModule} from './deposit/publications/depositPublicationsResults.module'; +import {DepositPublicationsResultComponent} from './deposit/publications/depositPublicationsResult.component'; + +import {SearchPublicationsModule} from './searchPages/simple/searchPublications.module'; +import {SearchPublicationsComponent} from './searchPages/simple/searchPublications.component'; +import {SearchDatasetsModule} from './searchPages/simple/searchDatasets.module'; +import {SearchDatasetsComponent} from './searchPages/simple/searchDatasets.component'; +import {SearchSoftwareModule} from './searchPages/simple/searchSoftware.module'; +import {SearchSoftwareComponent} from './searchPages/simple/searchSoftware.component'; +import {SearchDataProvidersModule} from './searchPages/simple/searchDataProviders.module'; +import {SearchDataprovidersComponent} from './searchPages/simple/searchDataproviders.component'; +import {SearchProjectsModule} from './searchPages/simple/searchProjects.module'; +import {SearchProjectsComponent} from './searchPages/simple/searchProjects.component'; +import {SearchOrganizationsModule} from './searchPages/simple/searchOrganizations.module'; +import {SearchOrganizationsComponent} from './searchPages/simple/searchOrganizations.component'; + +import {AdvancedSearchPublicationsModule} from './searchPages/advanced/advancedSearchPublications.module'; +import {AdvancedSearchPublicationsComponent} from './searchPages/advanced/advancedSearchPublications.component'; +import {AdvancedSearchDatasetsModule} from './searchPages/advanced/advancedSearchDatasets.module'; +import {AdvancedSearchDatasetsComponent} from './searchPages/advanced/advancedSearchDatasets.component'; +import {AdvancedSearchSoftwareModule} from './searchPages/advanced/advancedSearchSoftware.module'; +import {AdvancedSearchSoftwareComponent} from './searchPages/advanced/advancedSearchSoftware.component'; +import {AdvancedSearchDataProvidersModule} from './searchPages/advanced/advancedSearchDataProviders.module'; +import {AdvancedSearchDataProvidersComponent} from './searchPages/advanced/advancedSearchDataProviders.component'; +import {AdvancedSearchProjectsModule} from './searchPages/advanced/advancedSearchProjects.module'; +import {AdvancedSearchProjectsComponent} from './searchPages/advanced/advancedSearchProjects.component'; +import {AdvancedSearchOrganizationsModule} from './searchPages/advanced/advancedSearchOrganizations.module'; +import {AdvancedSearchOrganizationsComponent} from './searchPages/advanced/advancedSearchOrganizations.component'; + + +import {EntityRegistriesModule} from './searchPages/dataProviders/entityRegistries.module'; +import {SearchEntityRegistriesComponent} from './searchPages/dataProviders/entityRegistries.component'; + +import {CompatibleDataProvidersModule} from './searchPages/dataProviders/compatibleDataProviders.module'; +import {SearchCompatibleDataprovidersComponent} from './searchPages/dataProviders/compatibleDataProviders.component'; + +@NgModule({ + + imports: [ + SharedModule, + NoopAnimationsModule, + CommonModule, + HttpModule, + SharedComponentsModule, + CookieLawModule, + MainSearchModule, + ErrorModule, + DepositDatasetsModule,DepositDatasetsResultsModule, DepositBySubjectResultsModule,DepositPublicationsModule , DepositPublicationsResultsModule, + SearchPublicationsModule,SearchDatasetsModule, SearchSoftwareModule, SearchDataProvidersModule, SearchProjectsModule, SearchOrganizationsModule, + AdvancedSearchPublicationsModule,AdvancedSearchDatasetsModule, AdvancedSearchSoftwareModule, AdvancedSearchDataProvidersModule, AdvancedSearchProjectsModule, AdvancedSearchOrganizationsModule, + PublicationModule, DatasetModule, DataProviderModule, OrganizationModule, ProjectModule, SoftwareModule, + EntityRegistriesModule,CompatibleDataProvidersModule, + BrowserModule.withServerTransition({appId: 'my-app'}), + RouterModule.forRoot([ + { path: '', component: SearchComponent}, + { path: 'home', component: SearchComponent}, + { path: 'search/publication', component: PublicationComponent }, + { path: 'search/dataset', component: DatasetComponent}, + { path: 'search/software', component: SoftwareComponent}, + { path: 'search/project', component: ProjectComponent }, + { path: 'search/dataprovider', component: DataProviderComponent }, + { path: 'search/organization', component: OrganizationComponent }, + { path: 'participate/deposit-datasets', component: DepositDatasetsComponent }, + { path: 'participate/deposit-datasets-result', component: DepositDatasetsResultComponent}, + { path: 'participate/deposit-subject-result', component: DepositBySubjectResultComponent }, + { path: 'participate/deposit-publications', component: DepositPublicationsComponent }, + { path: 'participate/deposit-publications-result', component: DepositPublicationsResultComponent}, + { path: 'search/find', component: SearchComponent}, + { path: 'search/find/publications', component: SearchPublicationsComponent }, + { path: 'search/find/datasets', component:SearchDatasetsComponent}, + { path: 'search/find/software', component:SearchSoftwareComponent}, + { path: 'search/find/projects', component:SearchProjectsComponent}, + { path: 'search/find/dataproviders', component:SearchDataprovidersComponent }, + { path: 'search/find/organizations', component:SearchOrganizationsComponent }, + { path: 'search/content-providers', component: SearchCompatibleDataprovidersComponent}, + { path: 'search/content-providers-table', loadChildren: './searchPages/dataProviders/compatibleDataProvidersTable.module#CompatibleDataProvidersTableModule' }, + { path: 'search/entity-registries',component: SearchEntityRegistriesComponent}, + { path: 'search/entity-registries-table', loadChildren: './searchPages/dataProviders/entityRegistriesTable.module#EntityRegistriesTableModule' }, + { path: 'search/journals', loadChildren: './searchPages/dataProviders/journals.module#JournalsModule' }, + { path: 'search/journals-table', loadChildren: './searchPages/dataProviders/journalsTable.module#JournalsTableModule' }, + { path: 'search/advanced/publications', component: AdvancedSearchPublicationsComponent }, + { path: 'search/advanced/datasets', component: AdvancedSearchPublicationsComponent }, + { path: 'search/advanced/software', component: AdvancedSearchPublicationsComponent }, + { path: 'search/advanced/organizations',component: AdvancedSearchPublicationsComponent }, + { path: 'search/advanced/dataproviders', component: AdvancedSearchPublicationsComponent }, + { path: 'search/advanced/projects', component: AdvancedSearchPublicationsComponent }, + { path: 'project-report', loadChildren: './landingPages/htmlProjectReport/htmlProjectReport.module#HtmlProjectReportModule' }, + { path: 'myclaims', loadChildren: './claims/myClaims/myClaims.module#MyClaimsModule' }, + { path: 'claims', loadChildren: './claims/claimsAdmin/claimsAdmin.module#ClaimsAdminModule' }, + { path: 'participate/claim', loadChildren: './claims/linking/linkingGeneric.module#LinkingGenericModule' }, + { path: 'participate/direct-claim', loadChildren: './claims/directLinking/directLinking.module#DirectLinkingModule' }, + { path: 'claims-project-manager', loadChildren: './claims/claimsByToken/claimsByToken.module#ClaimsByTokenModule' }, + { path: 'reload', loadChildren: './reload/reload.module#ReloadModule' }, + { path: 'user-info', loadChildren: './login/user.module#UserModule' }, + { path: 'error', component: ErrorPageComponent }, + { path: '**',pathMatch: 'full',component: ErrorPageComponent } + + + ]), + ], + declarations: [ AppComponent ], + exports: [ AppComponent ], + providers:[ Meta, ConfigurationService], + bootstrap: [AppComponent] +}) +export class AppModule {} diff --git a/app.server.module.ts b/app.server.module.ts new file mode 100644 index 00000000..79602ec8 --- /dev/null +++ b/app.server.module.ts @@ -0,0 +1,20 @@ +import {NgModule} from '@angular/core'; +import {ServerModule} from '@angular/platform-server'; +import {ModuleMapLoaderModule} from '@nguniversal/module-map-ngfactory-loader'; + +import {AppModule} from './app.module'; +import {AppComponent} from './app.component'; + +@NgModule({ + imports: [ + // The AppServerModule should import your AppModule followed + // by the ServerModule from @angular/platform-server. + AppModule, + ServerModule, + ModuleMapLoaderModule, + ], + // Since the bootstrapped component is not inherited from your + // imported AppModule, it needs to be repeated here. + bootstrap: [AppComponent], +}) +export class AppServerModule {} diff --git a/claims/claim-utils/claim.ts b/claims/claim-utils/claim.ts new file mode 100644 index 00000000..b5378c5f --- /dev/null +++ b/claims/claim-utils/claim.ts @@ -0,0 +1,15 @@ +export class Claim { + id: string; + sourceType: string; + targetType: string; + sourceId: string; + targetId: string; + date: string; + DOI: string; + project: Project + userMail: string; + +} +export class Project{ + +} diff --git a/claims/claim-utils/claimContextSearchForm.component.ts b/claims/claim-utils/claimContextSearchForm.component.ts new file mode 100644 index 00000000..f3938127 --- /dev/null +++ b/claims/claim-utils/claimContextSearchForm.component.ts @@ -0,0 +1,367 @@ +import {Component, Input,Output, EventEmitter, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router} from '@angular/router'; +import {ContextsService} from './service/contexts.service'; +import {ClaimContext} from './claimEntities.class'; +import { StaticAutoCompleteComponent } from '../../utils/staticAutoComplete/staticAutoComplete.component'; +declare var UIkit:any; +import {Session} from '../../login/utils/helper.class'; +import {ErrorCodes} from '../../login/utils/guardHelper.class'; + +@Component({ + // moduleId: module.id, + selector: 'claim-contexts-search-form', + template: ` + +
+ + + + + + +
+ + + + + +
+ + +
+
Or Browse through categories
+ +
+ + +
+ + ` + +}) +export class ClaimContextSearchFormComponent { +// @Input() public inline:boolean = false ; // for claimed started from landing pages +public showComponent:boolean = true ; // for claimed started from landing pages +@Input() public selectedList; +//The following need to be kept in case we have to save the current state +@Input() public projects; +@Input() public results; +@Input() public inlineEntity; +public selectedCommunityId:string = "0"; +public selectedCategoryId:string ="0"; +// @Output() contextSelected = new EventEmitter(); + +@ViewChild (StaticAutoCompleteComponent) autocomplete : StaticAutoCompleteComponent ; + +public query = ''; +public filteredList = []; +public communities:any; +public selectedCommunityLabel:string = "Community:"; + +public categories:any; +public selectedCategoryLabel:string ="Category:"; +public concepts = []; +public conceptsClass = []; +public conceptsClassDisplay = []; +public conceptsCategoryLoading = []; +public warningMessage = ""; +public infoMessage = ""; +public loading:boolean = false; +public error:boolean = false; + +ngOnInit() { + this.getCommunities(); +} +constructor(private _contextService: ContextsService,private router: Router) { + +} + +select($event){ + var item = $event.value; + this.addNewContext( this.selectedCommunityLabel, this.selectedCategoryLabel, item); + } +isSelected(id):boolean{ + for (var _i = 0; _i < this.selectedList.length; _i++) { + let item = this.selectedList[_i]; + if(item.concept.id == id){ + return true; + // this.warningMessage = "Concept already in selected list"; + } + } + return false; +} + addNewContext(community,category,concept){ + var context: ClaimContext= { community: community, category: category, concept: concept }; + var found:boolean = false; + this.warningMessage = ""; + if (!this.isSelected(context.concept.id)) { + + this.selectedList.push(context); + UIkit.notification({ + message : 'A new concept is selected.', + status : 'primary', + timeout : 1000, + pos : 'top-center' + }); + + }else{ + UIkit.notification({ + message : 'The concept is already on your list.', + status : 'warning', + timeout : 1000, + pos : 'top-center' + }); + } +} + +getCommunities () { + if(!Session.isValidAndRemove()){ + this.saveStateAndRedirectLogin(); + + }else{ + this.loading = true; + var token=Session.getUserJwt(); + this._contextService.getCommunities().subscribe( + data => { + this.communities = data.communities; + this.loading = false; + }, + err => { + console.log(err); + this.loading = false; + this.error = true; + } + ); + } + } + getCategories () { + this.loading = true; + this.categories=[]; + if(this.selectedCommunityId != '0'){ + if(!Session.isValidAndRemove()){ + this.saveStateAndRedirectLogin(); + + }else{ + var token=Session.getUserJwt(); + this._contextService.getCategories(this.selectedCommunityId).subscribe( + data => { + + this.categories = (Array.isArray(data.category))? data.category:[data.category]; + this.concepts = []; + this.addCommunityInConcepts(); + this.filteredList = []; + if (this.query !== ""){ + var event = {value: ""}; + event.value = this.query; + } + this.loading = false; + }, + err => { + console.log(err); + this.loading = false; + } + ); + } + } + } + getConcepts () { + this.loading = true; + if(this.selectedCategoryId != '0'){ + if(!Session.isValidAndRemove()){ + this.saveStateAndRedirectLogin(); + }else{ + this.concepts = []; + var token=Session.getUserJwt(); + this._contextService.getConcepts(this.selectedCategoryId, "",true).subscribe( + data => { + + this.concepts =data; + this.addCommunityInConcepts(); + if (this.query !== ""){ + var event = {value: ""}; + event.value = this.query; + // this.filter(event); + } + this.loading = false; + }, + err => { + console.log(err); + this.loading = false; + } + ); + } + }else{ + this.concepts=[]; + this.loading = false; + } + } + displaySubcategory(id) { + if(this.conceptsClassDisplay[id] != null){ + this.conceptsClassDisplay[id] = !this.conceptsClassDisplay[id]; + + }else{ + this.conceptsClassDisplay[id] = true; + } + } + browseConcepts (categoryId) { + if(!Session.isValidAndRemove()){ + this.saveStateAndRedirectLogin(); + }else{ + if(this.conceptsClass[categoryId] != null){ + this.conceptsClassDisplay[categoryId] = !this.conceptsClassDisplay[categoryId]; + return; + }else{ + this.conceptsClassDisplay[categoryId] = true; + } + this.conceptsClass[categoryId] = []; + var token=Session.getUserJwt(); + this.conceptsCategoryLoading[categoryId] = true; + this._contextService.getConcepts(categoryId, "",false).subscribe( + data => { + var concepts = (Array.isArray(data))? data:[data]; + for(var i=0;i { + console.log(err); + this.conceptsCategoryLoading[categoryId] = false; + } + ); + } + + } + communityChanged(){ + console.log(this.selectedCommunityId +" "); + this.warningMessage = ""; + this.infoMessage = ""; + for(var i = 0; i< this.communities.length; i++){ + if(this.communities[i].id==this.selectedCommunityId){ + this.selectedCommunityLabel = this.communities[i].label; + break; + } + } + this.selectedCategoryId = "0"; + this.selectedCategoryLabel="Select Category:"; + this.getCategories(); + } + categoryChanged(){ + this.warningMessage = ""; + this.infoMessage = ""; + for(var i = 0; i< this.categories.length; i++){ + if(this.categories[i].id==this.selectedCategoryId){ + this.selectedCategoryLabel = this.categories[i].label; + break; + } + } + this.getConcepts(); + } +addCommunityInConcepts(){ + this.concepts.push({"id":this.selectedCommunityId, "label":this.selectedCommunityLabel}); + this.autocomplete.updateList(this.concepts); +} +saveStateAndRedirectLogin(){ + if(this.projects != null){ + localStorage.setItem("projects", JSON.stringify(this.projects)); + } + localStorage.setItem("contexts", JSON.stringify(this.selectedList)); + if(this.results != null){ + localStorage.setItem("results", JSON.stringify(this.results)); + } + if(this.inlineEntity != null){ + localStorage.setItem("inlineEntity", JSON.stringify(this.inlineEntity)); + } + + this.router.navigate(['/user-info'], { queryParams: { "errorCode": ErrorCodes.NOT_VALID, "redirectUrl": this.router.url } }); +} +} diff --git a/claims/claim-utils/claimContextSearchForm.module.ts b/claims/claim-utils/claimContextSearchForm.module.ts new file mode 100644 index 00000000..345d2c93 --- /dev/null +++ b/claims/claim-utils/claimContextSearchForm.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import { ClaimContextSearchFormComponent } from './claimContextSearchForm.component'; + import{ContextsServiceModule} from './service/contextsService.module'; + import {StaticAutocompleteModule} from '../../utils/staticAutoComplete/staticAutoComplete.module'; + import { RouterModule } from '@angular/router'; + +@NgModule({ + imports: [ + SharedModule,RouterModule, + ContextsServiceModule, + StaticAutocompleteModule + + ], + declarations: [ + ClaimContextSearchFormComponent + ], exports: [ClaimContextSearchFormComponent ] +}) +export class ClaimContextSearchFormModule { } diff --git a/claims/claim-utils/claimEntities.class.ts b/claims/claim-utils/claimEntities.class.ts new file mode 100644 index 00000000..7d866cea --- /dev/null +++ b/claims/claim-utils/claimEntities.class.ts @@ -0,0 +1,100 @@ +//Classes used in linking / inlinelinking when selecting an entity +export class ClaimResult{ + public id: string; + public type: string; + public source: string; + public title: string; + public url: string; + public result: any; + public accessRights: string = "OPEN"; + public embargoEndDate: string; + public date: string; + public authors: string[] =[]; + public publisher: string; + public description: string; + public resourceType:string; + + public static generateResult(item, itemId,itemSource,itemType, itemUrl, itemTitle, date, accessmode){ + + var result: ClaimResult = new ClaimResult(); + result.id = itemId; + result.type = itemType; + result.source = itemSource; + + result.title = (Array.isArray(itemTitle) && itemTitle.length > 0 )?itemTitle[0]:itemTitle; + result.url = itemUrl; + result.accessRights = 'OPEN'; + result.date = date; + result.result = item; + if(item.publisher){ + result.publisher = item.publisher; + } + + if(itemSource == 'datacite'){ + + result.publisher = item.attributes['container-title']; + if(item.attributes.author){ + result.authors =[] + for(var i=0; i< item.attributes.author.length; i++){ + result.authors.push((item.attributes.author[i].family)?item.attributes.author[i].family+', '+item.attributes.author[i].given:item.attributes.author[i].literal); + } + } + + // result = {id: itemId, type :itemType, source : itemSource, title: itemTitle,url: itemUrl, result: item, accessRights: 'OPEN', embargoEndDate: this.nextDate, date : date}; + }else if (itemSource == 'openaire'){ + //TODO put right access rights + // result = {id:itemId, type :itemType, source : itemSource, title: itemTitle,url: itemUrl, result: item, accessRights: accessMode, embargoEndDate: this.nextDate, date: date}; + // result = {id:itemId, type :itemType, source : itemSource, title: itemTitle,url: itemUrl, result: item, accessRights: accessmode, embargoEndDate: this.nextDate, date : date}; + result.embargoEndDate = accessmode; + + }else if(itemSource == 'crossref'){ + date = (date == null) ? null : date.substring(0,10); + result.date = date; + result.resourceType = item.type; + result.description = item.abstract; + if(item.author){ + result.authors =[] + for(var i=0; i< item.author.length; i++){ + result.authors.push(item.author[i].family +" "+ item.author[i].given ); + } + } + // result = {id: itemId, type :itemType, source : itemSource, title: itemTitle,url: itemUrl, result: item, accessRights: 'OPEN', embargoEndDate: this.nextDate, date: date}; + }else if (itemSource == 'orcid'){ + date = (date == null) ? null : date + "-01.-01" + result.date = date; + if(item['work-type']){ + result.resourceType = item.type; + + } + if(item.contributors){ + result.authors =[] + for(var i=0; i< item.contributors.length; i++){ + result.authors.push(item.contributors[i]); + } + } + + } + return result; + } +} +export class ClaimProject{ + public funderId: string; + public funderName: string; + public projectId: string; + public projectName: string; + public projectAcronym: string; + public startDate: string; + public endDate: string; + public code: string; + public jurisdiction: string; + public fundingLevel0: string; + + +} + +export class ClaimContext{ + public community: string; + public category: string; + public concept:any; + +} diff --git a/claims/claim-utils/claimProjectSearchForm.component.ts b/claims/claim-utils/claimProjectSearchForm.component.ts new file mode 100644 index 00000000..9a217dcd --- /dev/null +++ b/claims/claim-utils/claimProjectSearchForm.component.ts @@ -0,0 +1,191 @@ +import {Component, Input,Output, ElementRef, EventEmitter, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {SearchProjectsService} from '../../services/searchProjects.service'; +import {ProjectService} from '../../landingPages/project/project.service'; +// import {ModalLoading} from '../../utils/modal/loading.component'; +import { Subject } from 'rxjs/Subject'; +import {ClaimProject} from './claimEntities.class'; +declare var UIkit:any; +@Component({ + selector: 'claim-projects-search-form', + + template: ` +
+
+ +
+ +
+
+ + +
+ +
+ +
+ ` + +}) +export class ClaimProjectsSearchFormComponent { + ngOnInit() { + this.getFunders(); + } + // @ViewChild (ModalLoading) loading : ModalLoading ; + + // @Input() public inline: boolean = false ; // for claimed started from landing pages + public query = ''; + @Input() public selectedProjects=[] ; + public elementRef; + + public funders:string[]; + public selectedFunderId:string ="0"; + selectedFunderName:string ="Select funder:"; + @Output() projectSelected = new EventEmitter(); + + public projects:string[]; + public warningMessage = ""; + public infoMessage = ""; + + // public searchTermStream = new Subject(); + // filtered: Observable<{}> = this.searchTermStream + // .debounceTime(300).distinctUntilChanged() + // .switchMap((term: string) => this._projectService.searchForProjectsObs(term, this.selectedFunderId)); + public tries:number = 0 ; + public keywordlimit = 3; + +constructor(private _service: ProjectService, private _projectService: SearchProjectsService, myElement: ElementRef) { + this.elementRef = myElement; +} + + +// search() { +// console.info("heeere "+this.query ); +// this.infoMessage = ""; +// // this.filtered = []; +// if(this.query == ""){ +// this.tries = 0; +// this.warningMessage = ""; +// } else if(this.query && this.query.length < this.keywordlimit){ +// this.tries++; +// if(this.tries == this.keywordlimit -1 ){ +// this.warningMessage = "Type at least " + this.keywordlimit + " characters"; +// this.tries = 0; +// } +// }else{ +// console.info("doo the search "+this.query ); +// +// this.tries = 0; +// this.warningMessage = ""; +// this.searchTermStream.next(this.query); +// +// } +// +// } +select(item){ + this.query = ""; + // this.searchTermStream.next(this.query); //clear + item = item.value; + var project: ClaimProject = new ClaimProject(); + project.funderId = (this.selectedFunderId=="0")?item.funderId:this.selectedFunderId; + project.funderName = (this.selectedFunderId=="0")?item.funderName:this.selectedFunderName; + project.projectId = item.id; + project.projectName = item.projectName; + project.projectAcronym = item.projectAcronym; + project.startDate = item.startDate; + project.endDate = item.endDate; + project.code = item.code; + project.jurisdiction = item.jurisdiction; + project.fundingLevel0 = item.fundingLevel0; + + console.log(item); + + + // this._service.getProjectDates(project.projectId).subscribe( + // data => { + // project.startDate = data.startDate; + // project.endDate = data.endDate; + // }, + // err => console.log(err) + // ); + var index:number =this.selectedProjects.indexOf(project); + var found:boolean = false; + this.warningMessage = ""; + + for (var _i = 0; _i < this.selectedProjects.length; _i++) { + let item = this.selectedProjects[_i]; + if(item.projectId == project.projectId){ + found=true; + this.warningMessage = "Project already in selected list"; + } + } + + if (!found) { + this.selectedProjects.push(project); + this.projectSelected.emit({ + value: true + }); + UIkit.notification({ + message : 'A new project is selected.', + status : 'primary', + timeout : 1000, + pos : 'top-center' + }); + }else{ + UIkit.notification({ + message : 'The project is already on your list.', + status : 'warning', + timeout : 1000, + pos : 'top-center' + }); + } + +} +showItem(item):string{ + return ((item.field[1]['@value'])?item.field[1]['@value']+" - ":"" ) + item.field[3]['@value']; +} +remove(item){ + var index:number =this.selectedProjects.indexOf(item); + if (index > -1) { + this.selectedProjects.splice(index, 1); + } + +} +handleClick(event){ + var clickedComponent = event.target; + var inside = false; + do { + if (clickedComponent === this.elementRef.nativeElement) { + inside = true; + } + clickedComponent = clickedComponent.parentNode; + } while (clickedComponent); + +} +getFunders () { + console.info("Getting Funders...."); + this._projectService.getFunders().subscribe( + data => { + this.funders = data[1]; + console.log("this.funders"); + }, + err => console.log(err) + ); + } + + getProjects () { + if(this.selectedFunderId != '0'){ + + } + } +funderChanged(funderId:string, funderName:string){ + this.selectedFunderId = funderId; + this.selectedFunderName = funderName; + console.info("Selected funder:"+this.selectedFunderId+ ' name:'+funderName ); + +} + +} diff --git a/claims/claim-utils/claimProjectSearchForm.module.ts b/claims/claim-utils/claimProjectSearchForm.module.ts new file mode 100644 index 00000000..660cb500 --- /dev/null +++ b/claims/claim-utils/claimProjectSearchForm.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import { CommonModule } from '@angular/common'; + +import {ClaimProjectsSearchFormComponent} from './claimProjectSearchForm.component'; +// import {LoadingModalModule} from '../../utils/modal/loadingModal.module'; + +import {ProjectServiceModule} from '../../landingPages/project/projectService.module'; +import {ProjectsServiceModule} from '../../services/projectsService.module'; +import {EntitiesAutocompleteModule} from '../../utils/entitiesAutoComplete/entitiesAutoComplete.module'; + + @NgModule({ + imports: [ + SharedModule, CommonModule, + // LoadingModalModule, + ProjectServiceModule, ProjectsServiceModule, EntitiesAutocompleteModule + ], + providers:[ + ], + declarations: [ + ClaimProjectsSearchFormComponent + + ], + exports: [ClaimProjectsSearchFormComponent ] +}) +export class ClaimProjectsSearchFormModule { } diff --git a/claims/claim-utils/claimResultSearchForm.component.html b/claims/claim-utils/claimResultSearchForm.component.html new file mode 100644 index 00000000..901bb93d --- /dev/null +++ b/claims/claim-utils/claimResultSearchForm.component.html @@ -0,0 +1,222 @@ + +
+ + + + + + +
+
+ + +
+
+ + + + +
+
+ +
+
+
+
    +
  • +
    + {{item.title}} + {{item.title}} + +
    + + + +
  • +
+
+
+
+
+
+ + + + +
+
+ +
+
+
+
    +
  • +
    + {{result['title'].name}} + {{result['title'].name}} + +
    + + + + +
  • +
+
+
+
+
+
+ + + +
No results found
+ +
+ Results for + {{authorGivenName}} {{authorFamilyName}} - {{authorId}} : + +
Not the author you are looking for? + + + + + + + +
+ + +
+
+ +
+ +
+
+
    +
  • +
    + {{item['work-title']['title'].value}} + +
    + + + +
  • +
+
No results found
+
+
+
+
+
+ + + + +
+
+
+ +
+
+
+
    +
  • +
    + {{item.attributes.title}} + {{item.attributes.title}} + + +
    + + + +
  • +
+ +
+
+
+
+ + + + +
+
+
+ +
+
+
+
    +
  • +
    + {{result['title'].name}} + {{result['title'].name}} + + + + +
    + + + + +
  • +
+
+
+
+
+ + + + +
+
+
+ +
+
+
+
    +
  • +
    + {{result['title'].name}} + {{result['title'].name}} + + + + +
    + + + +
  • +
+
+
+
+
diff --git a/claims/claim-utils/claimResultSearchForm.component.ts b/claims/claim-utils/claimResultSearchForm.component.ts new file mode 100644 index 00000000..adb95fab --- /dev/null +++ b/claims/claim-utils/claimResultSearchForm.component.ts @@ -0,0 +1,643 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import {SearchCrossrefService} from '../claim-utils/service/searchCrossref.service'; +import {SearchOrcidService} from '../claim-utils/service/searchOrcid.service'; +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import { SearchDataciteService } from '../claim-utils/service/searchDatacite.service'; +import {SearchDatasetsService} from '../../services/searchDatasets.service'; +import {SearchSoftwareService} from '../../services/searchSoftware.service'; + +import { ErrorCodes} from '../../utils/properties/openaireProperties'; +import {ClaimResult} from '../claim-utils/claimEntities.class'; +import{DOI} from '../../utils/string-utils.class'; +declare var UIkit:any; + +@Component({ + selector: 'claim-result-search-form', + templateUrl: 'claimResultSearchForm.component.html', + +}) +export class ClaimResultSearchFormComponent { + constructor (private _searchDataciteService: SearchDataciteService, private _searchDatasetsService:SearchDatasetsService, private _searchSoftwareService:SearchSoftwareService, + private _searchCrossrefService: SearchCrossrefService,private _searchOrcidService: SearchOrcidService, private _searchPublicationsService: SearchPublicationsService, + private route: ActivatedRoute) { + var myDate = new Date(); + this.todayDate = myDate.getFullYear()+ "-" +(myDate.getMonth() + 1) + "-" + myDate.getDate() ; + this.nextDate = (myDate.getFullYear()+100)+ "-" +(myDate.getMonth() + 1) + "-" + myDate.getDate() ; + + } + ngOnInit() { + if(this.keyword !=null && this.keyword.length > 0){ + this.search(false); + } +} + + + page : number = 1; + size:number = 5; + navigateTo: string = "Search"; + source: string = "datacite"; + type : string = "dataset"; + showSearchResults:boolean=false; + // searchType ="publication"; + @Input() public select:boolean = true ; + @Input() public keyword:string = ''; + @Input() public selectedResults:ClaimResult[]; + // @Output() datasetsChange = new EventEmitter(); + // @Output() publicationsChange = new EventEmitter(); + + // @Output() resultsChange = new EventEmitter(); + + public errorCodes:ErrorCodes = new ErrorCodes(); + + dataciteResults=[]; + dataciteResultsNum:number = null; + // dataciteResultsNum : Observable = null; + dataciteStatus = this.errorCodes.NONE; + datacitePage : number = 1; + + openaireData=[]; + openaireDataNum:number = 0 ; + openaireDataStatus = this.errorCodes.NONE; + openaireDataPage : number = 1; + openaireSoftware=[]; + openaireSoftwareNum:number = 0 ; + openaireSoftwareStatus = this.errorCodes.NONE; + openaireSoftwarePage : number = 1; + + public warningMessage = ""; + public infoMessage = ""; + + public todayDate = ''; + public nextDate = ''; + public DOIs:string[] = []; + sub: any; + public searchSource:string = "openaire" + public activeTab:string = "openairePub" + + + crossrefResults=[]; + crossrefResultsNum : number = null; + crossrefPage : number = 1; + crossrefStatus:number = this.errorCodes.NONE; + + openairePubs = []; + openairePubsNum: number ; + openairePubsPage : number = 1; + openairePubsStatus:number = this.errorCodes.NONE; + + orcidResults: string[]; + orcidResultsNum: number ; + totalPages: number; + orcidResultsToShow: string[]; + orcidPage : number = 1; + orcidStatus:number = this.errorCodes.NONE; + authorId: string; + selectAuthorId: string = "0"; + authorGivenName: string; + authorFamilyName: string; + + authorIds: string[]; + authorGivenNames: string[]; + authorFamilyNames: string[]; + + authorsNum : number ; + + reloadOpenaire:boolean = true; + reloadCrossref:boolean = false; + reloadDatacite:boolean = false; + reloadOrcid:boolean = false; + + + + + search(sourceChanged){ + this.warningMessage = ""; + this.infoMessage = ""; + if(!sourceChanged){ + this.DOIs = DOI.getDOIsFromString(this.keyword); + this.reloadOpenaire = true; + this.reloadCrossref = true; + this.reloadDatacite = true; + this.reloadOrcid = true; + } + if((this.searchSource == "all" || this.searchSource == "openaire") && this.reloadOpenaire){ + this.searchOpenairePubs(this.keyword, this.size, 1); + this.searchOpenaireData(this.keyword,this.size,1); + this.searchOpenaireSoftware(this.keyword,this.size,1); + this.reloadOpenaire = false; + } + if((this.searchSource == "all" || this.searchSource == "crossref")&&this.reloadCrossref){ + this.getCrossrefResults(this.keyword, this.size,1); + this.reloadCrossref = false; + } + if((this.searchSource == "all" || this.searchSource == "datacite")&& this.reloadDatacite){ + this.searchDatacite(this.keyword,this.size,1); + this.reloadDatacite = false; + } + if((this.searchSource == "all" || this.searchSource == "orcid")&& this.reloadOrcid){ + this.searchOrcid(this.keyword); + this.reloadOrcid = false; + } + this.showSearchResults = true; + + } + +private getCrossrefResults (term: string, size : number, page : number) { + this.crossrefStatus = this.errorCodes.LOADING; + if( this.DOIs.length > 0 ){ + this._searchCrossrefService.searchCrossrefByDOIs(this.DOIs).subscribe( + data => { + if(data != null) { + this.crossrefResults = data.items; + this.crossrefPage=page; + this.crossrefResultsNum = data['total-results']; + if(data.items == 0){ + this._searchCrossrefService.searchCrossrefResults(term, size, page).subscribe( + data => { + if(data != null) { + this.crossrefResults = data.items; + this.crossrefPage=page; + this.crossrefResultsNum = data['total-results']; + this.crossrefStatus = this.errorCodes.DONE; + + }else{ + this.crossrefStatus = this.errorCodes.ERROR; + } + }, + err =>{ + console.log(err.status); + this.crossrefStatus = this.errorCodes.ERROR; + } + + ); + }else{ + this.crossrefStatus = this.errorCodes.DONE; + } + } + }, + err => { + //console.log(err); + this._searchCrossrefService.searchCrossrefResults(term, size, page).subscribe( + data => { + this.crossrefResults = data.items; + this.crossrefPage=page; + this.crossrefResultsNum = data['total-results']; + this.crossrefStatus = this.errorCodes.DONE; + + }, + err => { + console.log(err.status); + this.crossrefStatus = this.errorCodes.ERROR; + } + + ); + } + ); + + }else{ + + + this._searchCrossrefService.searchCrossrefResults(term, size, page).subscribe( + data => { + if(data != null) { + this.crossrefResults = data.items; + this.crossrefPage=page; + this.crossrefResultsNum = data['total-results']; + this.crossrefStatus = this.errorCodes.DONE; + + }else{ + this.crossrefStatus = this.errorCodes.ERROR; + } + + }, + err => { + console.log(err.status); + this.crossrefStatus = this.errorCodes.ERROR; + } + ); + } + } + private searchOpenairePubs(term: string, size : number, page : number) { + + if(this.DOIs.length > 0 ){ + this.openairePubsStatus = this.errorCodes.LOADING; + this._searchPublicationsService.searchPublicationsByDois(this.DOIs, null, page, size, []).subscribe( + data => { + if(data != null) { + this.openairePubsPage=page; + this.openairePubsNum = data[0]; + this.openairePubs = data[1]; + this.openairePubsStatus = this.errorCodes.DONE; + if(this.openairePubsNum == 0){ + this.openairePubsStatus = this.errorCodes.NONE; + } + }else { + this.openairePubsStatus = this.errorCodes.ERROR; + } + }, + err => { + this.openairePubsStatus = this.errorCodes.ERROR; + console.log(err.status); + } + ); + }else{ + this.openairePubsStatus = this.errorCodes.LOADING; + this._searchPublicationsService.searchPublications('q='+term, null, page, size, []).subscribe( + data => { + if(data != null) { + this.openairePubsPage=page; + this.openairePubsNum = data[0]; + this.openairePubs = data[1]; + this.openairePubsStatus = this.errorCodes.DONE; + if(this.openairePubsNum == 0){ + this.openairePubsStatus = this.errorCodes.NONE; + } + }else { + this.openairePubsStatus = this.errorCodes.ERROR; + } + }, + err => { + this.openairePubsStatus = this.errorCodes.ERROR; + console.log(err.status); + } + ); + } + } + + private searchOrcid (term: string) { + if(this.DOIs.length > 0){ + this.orcidStatus = this.errorCodes.NONE; + return; + } + this.orcidStatus = this.errorCodes.LOADING; + this.authorIds = new Array(); + this.authorGivenNames = new Array(); + this.authorFamilyNames = new Array(); + + this.getOrcidAuthor(term); + + console.info('searchOrcid in searchOrcid file'); + } + + private readData(data: any) { + this.authorIds.push(data[2].path); + + if(data[0] != null) { + this.authorGivenNames.push(data[0].value); + } else { + this.authorGivenNames.push(""); + } + if(data[1] != null) { + this.authorFamilyNames.push(data[1].value); + } else { + this.authorFamilyNames.push(""); + } + } + + private getOrcidAuthor (term: string) { + this.orcidResultsNum = null; + + //passing structures in order to fill them in service + this._searchOrcidService.searchOrcidAuthor(term, this.authorIds, + this.authorGivenNames, this.authorFamilyNames).subscribe( + data => { + if(data != null && data == true) { + this.getOrcidResultsByIndex(0); + } + + this.orcidStatus = this.errorCodes.NONE; + + }, + err => this.errorHandler(err, term) + + ); + } + + private errorHandler(err: any, term: string) { + if(err.status == 404){ + this.getOrcidAuthors(term); + } else { + this.orcidStatus = this.errorCodes.ERROR; + console.log(err.status); + + } + } + + private getOrcidAuthors (term: string) { + this.orcidResultsNum = null; + this.selectAuthorId = "0"; + this.orcidStatus = this.errorCodes.LOADING; + //passing structures in order to fill them in service + this._searchOrcidService.searchOrcidAuthors(term, this.authorIds, + this.authorGivenNames, this.authorFamilyNames).subscribe( + data => { + if(data != null && data == true) { + this.getOrcidResultsByIndex(0); + }else{ + this.orcidStatus = this.errorCodes.ERROR; + } + + }, + err => { + this.orcidStatus = this.errorCodes.ERROR; + console.log(err.status); + } + ); + } + + + private getOrcidResultsByIndex (index:number) { + if(this.authorIds.length > index) { + this.orcidStatus = this.errorCodes.LOADING; + let id = this.authorIds[index]; + this.authorGivenName = this.authorGivenNames[index]; + this.authorFamilyName = this.authorFamilyNames[index]; + this.getOrcidResultsById(id); + } + } + private getOrcidResultsById (id:string) { + if(id=="0"){ + return; + } + var index = this.authorIds.indexOf(id); + this.authorGivenName = this.authorGivenNames[index]; + this.authorFamilyName = this.authorFamilyNames[index]; + this.authorId = id; + console.info("getOrcidResultsById: "+id); + this.orcidStatus = this.errorCodes.LOADING; + this._searchOrcidService.searchOrcidPublications(id).subscribe( + data => { + if(data != null) { + this.orcidResults=data['orcid-work']; + this.orcidResultsNum = data['orcid-work'].length; + this.orcidPage = 1; + if((this.orcidResultsNum % this.size) == 0){ + this.totalPages=parseInt(''+(this.orcidResultsNum/this.size)); + } else{ + this.totalPages=parseInt(''+(this.orcidResultsNum/this.size+1)); + } + + this.orcidResultsToShow = this.orcidResults.slice(0,10); + + this.orcidStatus = this.errorCodes.DONE; + if(this.orcidResultsNum == 0){ + this.orcidStatus = this.errorCodes.NONE; + } + } else { + this.orcidResultsNum = 0; + this.totalPages=0; + this.orcidStatus = this.errorCodes.NONE; + } + + }, + err => { + console.log(err.status); + this.orcidStatus = this.errorCodes.ERROR; + } + ); + + + } + +/* +Is it USED??? +private remove(item){ + this.warningMessage = ""; + this.infoMessage = ""; + var index:number =this.selectedResults.indexOf(item); + item.selected=false; + if (index > -1) { + this.selectedResults.splice(index, 1); + // this.publicationsChange.emit({ + // value: this.selectedResults + // }); + } + + }*/ +private crossrefPageChange($event) { + this.crossrefPage=$event.value; + this.crossrefResults=[]; + console.log("Crossref chaenged "+this.crossrefPage); + this.getCrossrefResults(this.keyword,this.size,this.crossrefPage); +} +private orcidPageChange($event) { + this.orcidPage=$event.value; + this.orcidResultsToShow=[]; + this.orcidResultsToShow = this.orcidResults.slice(($event.value-1)*this.size, $event.value*this.size); +} +private openairePubsPageChange($event) { + this.openairePubsPage=$event.value; + this.searchOpenairePubs(this.keyword,this.size,this.openairePubsPage); +} +datacitePageChange($event) { + this.datacitePage=$event.value; + this.dataciteResults=[]; + this.searchDatacite(this.keyword,10,this.datacitePage); + this.warningMessage = ""; + this.infoMessage = ""; + +} +openaireDataPageChange($event) { + this.openaireDataPage=$event.value; + this.openaireData=[]; + this.searchOpenaireData(this.keyword,10,this.openaireDataPage); + this.warningMessage = ""; + this.infoMessage = ""; + +} +openaireSoftwarePageChange($event) { + this.openaireSoftwarePage=$event.value; + this.openaireSoftware=[]; + this.searchOpenaireSoftware(this.keyword,10,this.openaireSoftwarePage); + this.warningMessage = ""; + this.infoMessage = ""; + +} + + private isSelected(id:string){ + + var found:boolean = false; + this.warningMessage = ""; + for (var _i = 0; _i < this.selectedResults.length; _i++) { + let item = this.selectedResults[_i]; + if(item.id == id){ + found=true; + this.warningMessage = "Publication already in selected list"; + } + } + return found; + + + } + // isSelected(id:string){ + // + // var found:boolean = false; + // this.warningMessage = ""; + // for (var _i = 0; _i < this.selectedResults.length; _i++) { + // let item = this.selectedResults[_i]; + // if(item.id == id){ + // found=true; + // break; + // } + // } + // return found; + // } + private searchDatacite (term: string, size : number, page : number) { + this.getDataciteResults(term,size,page); + this.warningMessage = ""; + this.infoMessage = ""; + + } + private searchOpenaireData (term: string, size : number, page : number) { + if(this.DOIs.length > 0 ){ + this.openaireDataStatus = this.errorCodes.LOADING; + this._searchDatasetsService.searchDatasetsByDois(this.DOIs, null, page, size, []).subscribe( + data => { + if(data != null) { + this.openaireDataPage=page; + this.openaireDataNum = data[0]; + this.openaireData = data[1]; + this.openaireDataStatus = this.errorCodes.DONE; + if(this.openaireDataNum == 0){ + this.openaireDataStatus = this.errorCodes.NONE; + } + } + }, + err => { + this.openaireDataStatus = this.errorCodes.ERROR; + console.log(err.status); + } + ); + }else{ + this._searchDatasetsService.searchDatasets('q='+term+'', null, page, size, []).subscribe( + data => { + if(data != null) { + this.openaireDataPage=page; + this.openaireDataNum = data[0]; + this.openaireData = data[1]; + this.openaireDataStatus = this.errorCodes.DONE; + if(this.openaireDataNum == 0){ + this.openaireDataStatus = this.errorCodes.NONE; + } + } + }, + err => { + this.openaireDataStatus = this.errorCodes.ERROR; + console.log(err.status); + } + ); + } + this.warningMessage = ""; + this.infoMessage = ""; + + } + private searchOpenaireSoftware (term: string, size : number, page : number) { + if(this.DOIs.length > 0 ){ + this.openaireSoftwareStatus = this.errorCodes.LOADING; + this._searchSoftwareService.searchSoftwareByDois(this.DOIs, null, page, size, []).subscribe( + data => { + if(data != null) { + this.openaireSoftwarePage=page; + this.openaireSoftwareNum = data[0]; + this.openaireSoftware = data[1]; + this.openaireSoftwareStatus = this.errorCodes.DONE; + if(this.openaireSoftwareNum == 0){ + this.openaireSoftwareStatus = this.errorCodes.NONE; + } + } + }, + err => { + this.openaireSoftwareStatus = this.errorCodes.ERROR; + console.log(err.status); + } + ); + }else{ + this._searchSoftwareService.searchSoftware('q='+term+'', null, page, size, []).subscribe( + data => { + if(data != null) { + this.openaireSoftwarePage=page; + this.openaireSoftwareNum = data[0]; + this.openaireSoftware = data[1]; + this.openaireSoftwareStatus = this.errorCodes.DONE; + if(this.openaireSoftwareNum == 0){ + this.openaireSoftwareStatus = this.errorCodes.NONE; + } + } + }, + err => { + this.openaireSoftwareStatus = this.errorCodes.ERROR; + console.log(err.status); + } + ); + } + this.warningMessage = ""; + this.infoMessage = ""; + + } + private getDataciteResults (term: string, size : number, page : number) { + this._searchDataciteService.searchDataciteResults(term, size, page).subscribe( + data => { + this.dataciteResults = data.data; + this.datacitePage=page; + this.dataciteResultsNum = data.meta.total; + this.dataciteStatus = this.errorCodes.DONE; + + + }, + err => { + this.dataciteStatus = this.errorCodes.ERROR; + console.log(err); + } + + ); + } + + add(item, itemId,itemSource,itemType, itemUrl, itemTitle, date, accessmode){ + + console.log(' adding ' + itemType + " From " + itemSource+" "+ itemTitle); + var result: ClaimResult = ClaimResult.generateResult(item, itemId,itemSource,itemType, itemUrl, itemTitle, date, accessmode); + + + if (itemSource == 'orcid'){ + if(result.authors.length ==0 ){ + result.authors.push(this.authorGivenName + ', '+ this.authorFamilyName); + } + } + var found:boolean = this.isSelected( result.id); + + this.warningMessage = ""; + if (!found) { + this.selectedResults.push(result); + + UIkit.notification({ + message : 'A new research result is selected.', + status : 'primary', + timeout : 1000, + pos : 'top-center' + }); + + + }else{ + this.warningMessage = "Research Data already in selected list"; + UIkit.notification({ + message : 'The research result is already on your list.', + status : 'warning', + timeout : 1000, + pos : 'top-center' + }); + } + + } + + public searchSourceChanged(source){ + this.searchSource = source; + this.activeTab = (source == "openaire" || source == "all")?"openairePub":source; + if(this.keyword && this.keyword.length > 0){ + this.search(true); + } + } + public clickTab(tab){ + this.activeTab = tab; + } +} diff --git a/claims/claim-utils/claimResultSearchForm.module.ts b/claims/claim-utils/claimResultSearchForm.module.ts new file mode 100644 index 00000000..99b4fd65 --- /dev/null +++ b/claims/claim-utils/claimResultSearchForm.module.ts @@ -0,0 +1,29 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import { CommonModule } from '@angular/common'; +import {ClaimResultSearchFormComponent} from './claimResultSearchForm.component'; + +import {SearchDataciteServiceModule} from './service/searchDataciteService.module'; + +import {SearchCrossrefServiceModule} from './service/searchCrossrefService.module'; +import {SearchOrcidService} from './service/searchOrcid.service'; + +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import {SoftwareServiceModule} from '../../services/softwareService.module'; +import {PagingModule } from '../../utils/paging.module'; + + @NgModule({ + imports: [SharedModule, CommonModule, PublicationsServiceModule, DatasetsServiceModule, PagingModule, SearchCrossrefServiceModule, + SearchDataciteServiceModule,SoftwareServiceModule], + providers:[ + SearchOrcidService + ], + declarations: [ + ClaimResultSearchFormComponent + + ], + exports: [ClaimResultSearchFormComponent ] +}) +export class ClaimResultSearchFormModule { } diff --git a/claims/claim-utils/displayClaims/displayClaims.component.html b/claims/claim-utils/displayClaims/displayClaims.component.html new file mode 100644 index 00000000..5e385958 --- /dev/null +++ b/claims/claim-utils/displayClaims/displayClaims.component.html @@ -0,0 +1,115 @@ + +
+ +
+
+ +
+
+ + +
+ Filter By: +
+
+ + + + + +
+ +
+
+ +
+ +
+ +
+ Show + + + Showing {{(size*page - size +1)}} to {{(size*page>resultsNum)?resultsNum:(size*page)}} of {{resultsNum}} claims + +
+
+ + +
+ An Error occured. +
+
+ You are not allowed to access this page. +
+
+ User session is not valid. Please login again. +
+ + + +
+
+
+ You have selected {{selected.length}} claim(s) +
+
+
+ +
+ +
+
+ + +
+
No entries found.
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
Research Result Link to Claimed by Claimed Date
{{claim.userMail}}{{claim.date}}
+
+ +
+ + + + diff --git a/claims/claim-utils/displayClaims/displayClaims.component.ts b/claims/claim-utils/displayClaims/displayClaims.component.ts new file mode 100644 index 00000000..d6773c57 --- /dev/null +++ b/claims/claim-utils/displayClaims/displayClaims.component.ts @@ -0,0 +1,495 @@ +import {Component, ViewChild, Input} from '@angular/core'; +import {Location} from '@angular/common'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; +import {ClaimsService} from '../service/claims.service'; +import {ModalLoading} from '../../../utils/modal/loading.component'; +import {AlertModal} from '../../../utils/modal/alert'; +import {Session} from '../../../login/utils/helper.class'; + + +@Component({ + selector: 'displayClaims', + templateUrl: 'displayClaims.component.html', + providers:[ ClaimsService] + +}) +export class DisplayClaimsComponent { + constructor (private _claimService: ClaimsService, private route: ActivatedRoute, private _router:Router, private location: Location) { + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + if( this.myClaims){ + this.fetchBy = "User"; + this.fetchId = Session.getUserEmail(); + }else{ + + this.fetchBy = params['fetchBy']; + this.fetchBy = (this.types.indexOf(this.fetchBy) != -1)? this.fetchBy:'All'; + this.fetchId = params['fetchId']; + this.fetchId = this.fetchId?this.fetchId:''; + + } + + let page = (params['page']=== undefined)?1:+params['page']; + let size = (params['size']=== undefined)?10:+params['size']; + + this.keyword = (params['keyword']?params['keyword']:""); + this.inputkeyword = this.keyword; + this.page = ( page <= 0 ) ? 1 : page; + this.size = ( size <= 0 ) ? 10 : size; + this.entityTypes = []//(params['types']?params['types']:[]); + this.setTypes(params['types']); // check the appropriate checkboxes + this.setSortby(params['sort']); + this.getClaims(); + + }); + + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + //string because comes as input from component directive + @Input() enableDelete: boolean = false; + @Input() showUserEmail: boolean = true; + @Input() myClaims: boolean= false ; + @Input() isAdmin:boolean = false; + page : number; + size:number; + sizes = [10,20,30,50]; + keyword:string; // the keyword string to give to the request as parameter + inputkeyword:string; // the string written in the input field (keyword=inputkeyword when its length is bigger than 3 and the user stops typing) + lengths = [10,20,30,50]; + types = ["All","Project","Context","Result","User"]; + @Input() fetchBy:string; + @Input() fetchId:string; + + navigateTo: string = "Claims"; + resultsNum: number ; + claims: string[]; + + @ViewChild (ModalLoading) loading : ModalLoading ; + + //checkboxes: + publicationCB = false; + datasetCB = false; + softwareCB = false; + contextCB = false; + projectCB = false; + entityTypes : string[] =[] ; + + descending = true; + sortby = "date"; + + selected=[]; + deleteMessage:string = ""; + showErrorMessage:boolean = false; + showForbiddenMessage:boolean = false; + userValidMessage:string = ""; + + //params for pagingFormatter to use when navigate to page + params; + @ViewChild(AlertModal) alert; + + claimsDeleted:number = 0; + + getClaims () { + if(!Session.isValidAndRemove()){ + this.userValidMessage = "User session has expired. Please login again."; + + }else{ + var token=Session.getUserJwt(); + this.selected=[]; + var types = ''; + this.showErrorMessage = false; + this.showForbiddenMessage = false; + for (var type of this.entityTypes){ + types+=(types.length>0?'&':'')+"types="+type; + } + if(this.fetchBy =="Project" ){ + this._claimService.getClaimsByProject(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe( + data => { + this.claims = data.data; + this.resultsNum= data.total; + }, + err => { + this.handleErrors(err); + } + ); + }else if(this.fetchBy =="User"){ + this._claimService.getClaimsByUser(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe( + data => { + this.claims = data.data; + this.resultsNum= data.total; + }, + err => { + this.handleErrors(err); + } + ); + }else if(this.fetchBy =="Result"){ + this._claimService.getClaimsByResult(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe( + data => { + this.claims = data.data; + this.resultsNum= data.total; + }, + err => { + this.handleErrors(err); + } + ); + }else if(this.fetchBy =="Context"){ + this._claimService.getClaimsBycontext(this.size,this.page,this.fetchId,this.keyword,this.sortby,this.descending, types).subscribe( + data => { + this.claims = data.data; + this.resultsNum= null; + this.resultsNum= data.total;//data.length; //TODO get the total results num + }, + err => { + this.handleErrors(err); + } + ); + }else{ + this._claimService.getClaims(this.size,this.page,this.keyword,this.sortby,this.descending, types).subscribe( + data => { + this.claims = data.data; + this.resultsNum = null; + this.resultsNum= data.total;//data.length; //TODO get the total results num + }, + err => { + this.handleErrors(err); + } + ); + } + } +} +handleErrors(err){ + + this.showErrorMessage = true; + try{ + var error = err.json() + var code = error.code; + if(code == 403){ + this.showErrorMessage = false; + this.showForbiddenMessage = true; + } + }catch (e) { + console.log("Couldn't parse answer as json") + this.showErrorMessage = true; + } + +} + + goTo(page:number = 1){ + + this.page = page; + + this.location.go(location.pathname,this.getParametersString()); + this.getClaims(); + } + getParameters(){ + var params = {} + if(this.myClaims){ + params={ page: this.page, size: this.size, types: this.entityTypes, keyword : this.keyword, sort: this.getSortby() }; + }else{ + params={ page: this.page, size: this.size, types: this.entityTypes, fetchBy: this.fetchBy, fetchId:this.fetchId, keyword : this.keyword, sort: this.getSortby() }; + } + return params; + } + + getParametersString(){ + var params=''; + params+=(this.page==1?"":(params.length>0?'&':'')+"page="+this.page); + params+=(this.size==10?"":(params.length>0?'&':'')+"size="+this.size); + // params+=(this.entityTypes==''?"":(params.length>0?'&':'')+"types="+this.entityTypes); + var types=""; + for (var type of this.entityTypes){ + types+=(types.length>0?',':'')+type; + } + params+=(types.length>0)?"types="+types:""; + + if(this.isAdmin ){ + params+=(this.fetchBy=='All'?"":(params.length>0?'&':'')+"fetchBy="+this.fetchBy); + params+=(this.fetchId==''?"":(params.length>0?'&':'')+"fetchId="+this.fetchId); + } + params+=(this. getSortby()=='datedesc'?"":(params.length>0?'&':'')+"sort="+this. getSortby()); + params+=(this.keyword==''?"":(params.length>0?'&':'')+"keyword="+this.keyword); + return params; + } + changeSize(size: number ){ + this.goTo(); + } + + clearFilters(){ + this.keyword = ''; + this.inputkeyword = ''; + this.publicationCB = false; + this.projectCB = false; + this.datasetCB = false; + this.softwareCB = false; + this.contextCB = false; + this.entityTypes = []; + this.goTo(); + } + + changeOrderby(sortby:string){ + if(sortby==this.sortby){ + this.descending = !this.descending; + }else{ + this.sortby = sortby; + this.descending = false; + } + this.goTo(); + } + setSortby(sortby:string){ + if(!sortby|| sortby == "datedesc"){ + this.descending = true; + this.sortby = "date"; + }else if(sortby == "dateasc"){ + this.descending = false; + this.sortby = "date"; + }else if(sortby == "userasc"){ + this.descending = false; + this.sortby = "user"; + }else if(sortby == "userdesc"){ + this.descending = true; + this.sortby = "user"; + }if(sortby =="sourceasc"){ + this.descending = false; + this.sortby = "source"; + }else if(sortby == "sourcedesc"){ + this.descending = true; + this.sortby = "source"; + }else if(sortby == "targetasc"){ + this.descending = false; + this.sortby = "target"; + }else if(sortby == "targetdesc"){ + this.descending = true; + this.sortby = "target"; + } + } + getSortby():string{ + if(this.descending){ + return this.sortby+"desc"; + }else{ + return this.sortby+"asc"; + } + + } + changeType(){ + this.entityTypes = []; + if(this.publicationCB){ + this.entityTypes.push('publication'); + } + if(this.datasetCB){ + this.entityTypes.push('dataset'); + } + if(this.softwareCB){ + this.entityTypes.push('software'); + } + if(this.projectCB){ + this.entityTypes.push('project'); + } + if(this.contextCB){ + this.entityTypes.push('context'); + } + + this.goTo(); + } + setTypes(types:string){ + if(!types){ + return; + } + if(types.length > 0){ + this.entityTypes = []; + if(types.indexOf("publication")!=-1){ + this.publicationCB = true; + this.entityTypes.push("publication"); + } + if(types.indexOf("dataset")!=-1){ + this.datasetCB = true; + this.entityTypes.push("dataset"); + } + if(types.indexOf("software")!=-1){ + this.softwareCB = true; + this.entityTypes.push("software"); + } + if(types.indexOf("project")!=-1){ + this.projectCB = true; + this.entityTypes.push("project"); + } + if(types.indexOf("context")!=-1){ + this.contextCB = true; + this.entityTypes.push("context"); + } + } + if(this.publicationCB && this.datasetCB && this.softwareCB && this.contextCB && this.projectCB){ + this.entityTypes=[]; + } + } + changekeyword(){ + + if(this.inputkeyword.length >= 3 || this.inputkeyword.length == 0 ){ + this.keyword = this.inputkeyword; + this.page = 1; + this.goTo(); + } + + } + select(item:any,event){ + this.deleteMessage=""; + var value = event.currentTarget.checked; + if(value){ + this.selected.push(item); + }else{ + for (var _i = 0; _i < this.selected.length; _i++) { + let claim = this.selected[_i]; + if(claim['id'] == item.id){ + this.selected.splice(_i, 1); + } + } + + + } + } + selectAll(event){ + var value = event.currentTarget.checked; + if(value){ + this.selected = []; + for (var _i = 0; _i < this.claims.length; _i++) { + let claim = this.claims[_i]; + this.selected.push(claim); + } + this.deleteMessage = ""; + }else{ + this.selected = []; + this.deleteMessage=""; + } + } + + isSelected(id:string){ + for (var _i = 0; _i < this.selected.length; _i++) { + let claim = this.selected[_i]; + if(claim['id'] == id){ + return true; + } + } + return false; + } + + + confirmOpen(){ + if(this.selected.length <= 0){ + + }else{ + this.alert.cancelButton = true; + this.alert.okButton = true; + this.alert.alertTitle = "Delete "+this.selected.length+" claim(s)"; + this.alert.message = this.selected.length+" claims will be deleted. Do you want to proceed? "; + this.alert.okButtonText = "Yes"; + this.alert.cancelButtonText = "No"; + this.alert.open(); + } + } + confirmClose(data){ + this.delete(); + } + delete(){ + this.deleteMessage=""; + this.loading.open(); + this.claimsDeleted = 0; + var ids = []; + for (var i = 0; i < this.selected.length; i++){ + var id =this.selected[i].id; + ids.push(id); + // var selected =this.selected[i].id; + // console.warn("Deleting claim with id:"+id); + // this.deleteById(id); + //TODO for multiple concurrent + } + this.batchDeleteById(ids); + } + + deleteById(id:string){ + if(!Session.isValidAndRemove()){ + this.userValidMessage = "User session has expired. Please login again."; + + }else{ + var token=Session.getUserJwt(); + console.log("Deleting claim with id:"+id); + // this._claimService.deleteClaimById(id); + this._claimService.deleteClaimById(id).subscribe( + res => { + console.log('Delete response'+res.code ); + console.log("Deleted claim with id:"+ id); + //remove this claim from the + let newClaims=this.claims; + for (var _i = 0; _i < this.claims.length; _i++) { + let claim = this.claims[_i]; + if(claim['id'] == id){ + newClaims.splice(_i, 1); + } + } + //TODO should call getClaims??? + this.claimsDeleted++; + this.claims = newClaims; + if(this.claimsDeleted == this.selected.length){ + this.resultsNum = this.resultsNum - this.selected.length; + this.loading.close(); + this.selected = []; + } + + + }); + } + } + batchDeleteById(ids:string[]){ + if(!Session.isValidAndRemove()){ + this.userValidMessage = "User session has expired. Please login again."; + + }else{ + var token=Session.getUserJwt(); + console.warn("Deleting claim with ids:"+ids); + this._claimService.deleteBulk(ids).subscribe( + res => { + console.info('Delete response'+res.code ); + console.warn("Deleted ids:"+ res.deletedIds); + console.warn("Not found ids:"+ res.notFoundIds); + //remove this claim from the + let newClaims=this.claims; + for(var id of res.deletedIds){ + for (var _i = 0; _i < this.claims.length; _i++) { + let claim = this.claims[_i]; + if(claim['id'] == id){ + newClaims.splice(_i, 1); + } + } + for (var _i = 0; _i < this.selected.length; _i++) { + let claim = this.selected[_i]; + if(claim['id'] == id){ + this.selected.splice(_i, 1); + } + } + } + this.claims = newClaims; + this.resultsNum = this.resultsNum - res.deletedIds.length; + this.loading.close(); + if(res.deletedIds.length>0){ + this.deleteMessage=this.deleteMessage+'
'+res.deletedIds.length+' claim(s) successfully deleted.
'; + } + if(res.notFoundIds.length>0){ + this.deleteMessage=this.deleteMessage+'
'+res.notFoundIds.length+' claim(s) couldn\'t be deleted.
'; + } + }, err => { + console.log(err); + this.showErrorMessage = true; + this.loading.close(); + + }); + } + } + pageChange($event) { + var page:number = +$event.value + this.goTo(page); + } +} diff --git a/claims/claim-utils/displayClaims/displayClaims.module.ts b/claims/claim-utils/displayClaims/displayClaims.module.ts new file mode 100644 index 00000000..4c8e0bb0 --- /dev/null +++ b/claims/claim-utils/displayClaims/displayClaims.module.ts @@ -0,0 +1,26 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import {ClaimServiceModule} from '../service/claimsService.module'; +import {DisplayClaimsComponent} from './displayClaims.component'; +import {LoadingModalModule} from '../../../utils/modal/loadingModal.module'; +import {AlertModalModule} from '../../../utils/modal/alertModal.module'; +import {ClaimEntityFormatterModule} from '../entityFormatter/claimEntityFormatter.module'; +import {PagingModule } from '../../../utils/paging.module'; +import {HelperModule} from '../../../utils/helper/helper.module'; + + @NgModule({ + imports: [ + CommonModule, FormsModule, ClaimServiceModule, LoadingModalModule, AlertModalModule, +ClaimEntityFormatterModule, PagingModule, HelperModule + + ], + declarations: [ + DisplayClaimsComponent + + ], + exports: [ + DisplayClaimsComponent + ] +}) +export class DisplayClaimsModule { } diff --git a/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts b/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts new file mode 100644 index 00000000..8a1262a8 --- /dev/null +++ b/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts @@ -0,0 +1,48 @@ +import {Component, Input} from '@angular/core'; + +//Usage Example " " + +//externalUrl +@Component({ + selector: 'claim-entity', + template: ` +
+ + +
+
+ + +
+
+ + + + +
+
+ + +
+
+ + {{entity.title}} +
+ ` +}) + +export class ClaimEntityFormatter { + @Input() entity: string[]; + @Input() type: string; + + constructor () {} + + ngOnInit() { + if(this.type && this.type == "software"){ + + console.log(this.entity); + } + } + + +} diff --git a/claims/claim-utils/entityFormatter/claimEntityFormatter.module.ts b/claims/claim-utils/entityFormatter/claimEntityFormatter.module.ts new file mode 100644 index 00000000..01a1d0ac --- /dev/null +++ b/claims/claim-utils/entityFormatter/claimEntityFormatter.module.ts @@ -0,0 +1,24 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {ProjectTitleFormatter} from './projectTitleFormatter.component'; +import {PublicationTitleFormatter} from './publicationTitleFormatter.component'; +import {ClaimEntityFormatter} from './claimEntityFormatter.component'; + + @NgModule({ + imports: [ + CommonModule, RouterModule + ], + declarations: [ + ProjectTitleFormatter, PublicationTitleFormatter, ClaimEntityFormatter + + ], + providers: [ ], + exports: [ + ProjectTitleFormatter, PublicationTitleFormatter, ClaimEntityFormatter + + ] +}) +export class ClaimEntityFormatterModule { } diff --git a/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts b/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts new file mode 100644 index 00000000..b1b95aa1 --- /dev/null +++ b/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts @@ -0,0 +1,25 @@ +import {Component, Input} from '@angular/core'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../../utils/routerHelper.class'; + +//Usage Example " " + +@Component({ + selector: 'project-title', + template: ` + + {{project['name']}} ({{project['funderName']}}) + + ` +}) + +export class ProjectTitleFormatter { + @Input() project: string[]; + public url:string; + public routerHelper:RouterHelper = new RouterHelper(); + constructor () {} + + ngOnInit() { + this.url = OpenaireProperties.getsearchLinkToProject() + "?projectId=" + this.project["openaireId"]; + } +} diff --git a/claims/claim-utils/entityFormatter/publicationTitleFormatter.component.ts b/claims/claim-utils/entityFormatter/publicationTitleFormatter.component.ts new file mode 100644 index 00000000..321e440d --- /dev/null +++ b/claims/claim-utils/entityFormatter/publicationTitleFormatter.component.ts @@ -0,0 +1,26 @@ +import {Component, Input} from '@angular/core'; + +//Usage Example " " + +@Component({ + selector: 'publication-title', + template: ` + + {{title}} + {{title}} + + ` +}) + +export class PublicationTitleFormatter { + @Input() title: string[]; + @Input() url: string[]; + + constructor () {} + + ngOnInit() { + + } + + +} diff --git a/claims/claim-utils/service/claims.service.ts b/claims/claim-utils/service/claims.service.ts new file mode 100644 index 00000000..45107b3b --- /dev/null +++ b/claims/claim-utils/service/claims.service.ts @@ -0,0 +1,149 @@ +import {Injectable} from '@angular/core'; +import {URLSearchParams } from '@angular/http'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +// import {Claim} from '../claim'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../../../shared/cache.service'; +import { CustomOptions } from './customOptions.class'; +@Injectable() +export class ClaimsService { + private baseUrl; + constructor(private http: Http ) { + this.baseUrl = OpenaireProperties.getClaimsAPIURL(); + } + + private getClaimRequest(size : number, page : number, url :string, fromCache:boolean):any { + console.info('ClaimsService: Claims request: '+url); + let key = url; + //(fromCache && OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url + return this.http.get(url, CustomOptions.getAuthOptions()) + .map(request => request.json()) + .do(request => console.info("Get claims: offset = "+(size*(page-1)) + " limit ="+size )) + .catch(this.handleError); + } + getClaims( size : number, page : number, keyword:string, sortby: string, descending: boolean, types: string):any { + console.info('ClaimsService: getClaims ' ); + console.info('ClaimsService: Types : '+types ); + let url = this.baseUrl +"claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+"&"+types; + return this.getClaimRequest(size,page,url,true); + + } + getClaimsByUser( size : number, page : number, user:string, keyword:string, sortby: string, descending: boolean, types: string):any { + console.info('ClaimsService: getClaims for user : '+user); + let url = this.baseUrl +"users/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+"&"+types; + return this.getClaimRequest(size,page,url,false); + + } + getClaimsBycontext( size : number, page : number, contextId:string, keyword:string, sortby: string, descending: boolean, types: string ):any { + console.info('ClaimsService: getClaims for context : '+contextId); + let url = this.baseUrl +"contexts/"+contextId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+"&"+types; + return this.getClaimRequest(size,page,url,true); + + } + getClaimsByResult( size : number, page : number, resultId:string, keyword:string, sortby: string, descending: boolean, types: string ):any { + console.info('ClaimsService: getClaims for result : '+resultId); + let url = this.baseUrl +"results/"+resultId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+"&"+types; + return this.getClaimRequest(size,page,url,true); + + } + getClaimsByProject( size : number, page : number, projectId:string, keyword:string, sortby: string, descending: boolean, types: string ):any { + console.info('ClaimsService: getClaims for project : '+projectId); + let url = this.baseUrl +"projects/"+projectId+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+"&"+types; + return this.getClaimRequest(size,page,url,true); + } + + deleteClaimById(claimId:string ):any{ + console.warn('Trying to delete claim with id : '+claimId); + let url = this.baseUrl +"claims/"+claimId; + // let headers = new Headers({ 'Content-Type': 'application/json' }); + // let options = new RequestOptions({ headers: headers }); + return this.http.delete( url, CustomOptions.getAuthOptionsWithBody()).map(request => request.json()) + // .do(request => console.info("After delete" )) + .catch(this.handleError); + + } + deleteBulk(claimIds:string[]):any{ + + console.warn('Trying to delete claims with ids : '+claimIds); + var url = ""; + + for(var claimId of claimIds){ + url=url+(url.length >0 ?"&":"")+"claimId="+claimId; + } + url= this.baseUrl +"claims/bulk?"+url; + + // let headers = new Headers({ 'Content-Type': 'application/json' }); + // let options = new RequestOptions({ headers: headers }); + return this.http.delete( url, CustomOptions.getAuthOptions()).map(request => request.json()) + // .do(request => console.info("After delete" )) + .catch(this.handleError); + + } + insertBulkClaims(claims):any{ + console.warn('Trying toinsert claims : '+claims); + let url = this.baseUrl +"claims/bulk"; + let body = JSON.stringify( claims ); + console.warn('Json body: : '+body); + // let headers = new Headers({ 'Content-Type': 'application/json' }); + // let options = new RequestOptions({ headers: headers }); + return this.http.post(url, body, CustomOptions.getAuthOptionsWithBody()) + .map(res => res.json()) + .do(request => console.info("Insert Response:"+request.status) ) + .catch(this.handleError); + + } + insertClaim(claim):any{ + console.warn('Trying toinsert claim : '+claim); + let url = this.baseUrl +"claims"; + let body = JSON.stringify( claim ); + // let headers = new Headers({ 'Content-Type': 'application/json' }); + // let options = new RequestOptions({ headers: headers }); + return this.http.post(url, body, CustomOptions.getAuthOptionsWithBody()) + .map(res => res.json()) + .do(request => console.info("Insert Response:"+request.status) ) + .catch(this.handleError); + + } + insertDirectRecords(records):any{ + console.warn('Trying to feedrecords : '+records); + let url = this.baseUrl +"feed/bulk"; + let body = JSON.stringify( records ); + console.warn('Json body: : '+body); + // let headers = new Headers({ 'Content-Type': 'application/json' }); + // let options = new RequestOptions({ headers: headers }); + return this.http.post(url, body, CustomOptions.getAuthOptionsWithBody()) + .map(res => res.json()) + .do(request => console.info("Insert Response:"+request) ) + .catch(this.handleError); + + } + 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.log(error); + return Observable.throw(error || 'Server error'); + } + + getClaim(id:string):any { + let url = this.baseUrl+"claims/"+id; + return new Promise((resolve, reject) => { + this.http.get(url) + .map(res => res.json()) + .subscribe( + data => { + resolve(data.data); + }, + err => { + reject(err); + } + ) + ; + }); + } + + +} diff --git a/claims/claim-utils/service/claimsService.module.ts b/claims/claim-utils/service/claimsService.module.ts new file mode 100644 index 00000000..d38d0f8d --- /dev/null +++ b/claims/claim-utils/service/claimsService.module.ts @@ -0,0 +1,23 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {ClaimsService} from './claims.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + ClaimsService, + +], + exports: [ + ] +}) + + +export class ClaimServiceModule { } diff --git a/claims/claim-utils/service/contexts.service.ts b/claims/claim-utils/service/contexts.service.ts new file mode 100644 index 00000000..f5d15f70 --- /dev/null +++ b/claims/claim-utils/service/contexts.service.ts @@ -0,0 +1,85 @@ +import {Injectable} from '@angular/core'; +import {Jsonp, URLSearchParams, RequestOptions, Headers} from '@angular/http'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {Claim} from '../claim'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import {AutoCompleteValue} from '../../../searchPages/searchUtils/searchHelperClasses.class'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../../../shared/cache.service'; +import { COOKIE } from '../../../login/utils/helper.class'; +@Injectable() +export class ContextsService { + private baseUrl; + constructor(private http: Http ) { + this.baseUrl = OpenaireProperties.getClaimsAPIURL(); + } + + public getCommunities():any { + let url = this.baseUrl + 'communities'; + let key = url; + + + console.info('ContextsService: request communities '+url); + return this.http.get(url, this.getAuthOptions()) + .map(request => request.json().data) + // .do(request => console.info("Get claims: offset = ")) + .catch(this.handleError); + } + public getCategories(communityId :string):any { + console.info('ContextsService: request categories for community with id '+communityId); + let url= this.baseUrl + 'communities/' + communityId + '/categories'; + let key = url; + + + return this.http.get(url, this.getAuthOptions()) + .map(request => request.json().data) + // .do(request => console.info("Get claims: offset = " )) + .catch(this.handleError);; + } + public getConcepts(categoryId :string, keyword: string, parsing:boolean):any { + console.info('ContextsService: request concept for category with id '+categoryId + ' and keyword '+ keyword); + let url= this.baseUrl + 'categories/' + categoryId+ "/concepts"; + let key = url+"_parsing="+parsing; + + + return this.http.get(url, this.getAuthOptions()) + .map(request => request.json().data) + .catch(this.handleError) + .map(res => (parsing)?this.parse(res.concept):res.concept); + // .do(res => console.info("Result is "+ res.length )); + } + parse (data: any):AutoCompleteValue[] { + var array:AutoCompleteValue[] =[] + if(!Array.isArray(data) && data.id && data.label){ + var value:AutoCompleteValue = new AutoCompleteValue(); + value.id = data.id; + value.label = data.label; + array.push(value); + } + for(var i = 0; i < data.length; i++){ + var value:AutoCompleteValue = new AutoCompleteValue(); + value.id = data[i].id; + value.label = data[i].label; + array.push(value); + } + + return array; + + } + + 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.log(error); + return Observable.throw(error || 'Server error'); + } + private getAuthOptions():RequestOptions{ + let headers = new Headers(); + headers.append('X-XSRF-TOKEN', COOKIE.getCookie(COOKIE.cookieName_id)); + let options = new RequestOptions({ headers: headers, withCredentials:true }); + return options; + } +} diff --git a/claims/claim-utils/service/contextsService.module.ts b/claims/claim-utils/service/contextsService.module.ts new file mode 100644 index 00000000..6bd55ced --- /dev/null +++ b/claims/claim-utils/service/contextsService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {ContextsService} from './contexts.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + ContextsService +], + exports: [ + ] +}) +export class ContextsServiceModule { } diff --git a/claims/claim-utils/service/customOptions.class.ts b/claims/claim-utils/service/customOptions.class.ts new file mode 100644 index 00000000..7796c45e --- /dev/null +++ b/claims/claim-utils/service/customOptions.class.ts @@ -0,0 +1,19 @@ +import { RequestOptions, Headers} from '@angular/http'; +import { COOKIE } from '../../../login/utils/helper.class'; + + +export class CustomOptions{ + public static getAuthOptionsWithBody():RequestOptions{ + let headers = new Headers(); + headers.append('Content-Type', 'application/json'); + headers.append('X-XSRF-TOKEN', COOKIE.getCookie(COOKIE.cookieName_id)); + let options = new RequestOptions({ headers: headers, withCredentials:true }); + return options; + } + public static getAuthOptions():RequestOptions{ + let headers = new Headers(); + headers.append('X-XSRF-TOKEN', COOKIE.getCookie(COOKIE.cookieName_id)); + let options = new RequestOptions({ headers: headers, withCredentials:true }); + return options; + } +} diff --git a/claims/claim-utils/service/searchCrossref.service.ts b/claims/claim-utils/service/searchCrossref.service.ts new file mode 100644 index 00000000..40c4e993 --- /dev/null +++ b/claims/claim-utils/service/searchCrossref.service.ts @@ -0,0 +1,67 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +@Injectable() +export class SearchCrossrefService { + constructor( private http: Http ) {} + + + searchCrossrefResults (term: string, size : number, page : number):any { + let url = OpenaireProperties.getSearchCrossrefAPIURL()+'?query='+term+'&rows='+size+'&offset='+(size*(page-1)); + let key = url; + + return this.http.get(url) + .map(request => request.json().message) + .do(items => console.log("Crossref Results: total results = "+items['total-results']+" keyword = "+term)); + //.catch(this.handleError); + + } + searchCrossrefByDOIs(DOIs: string[]):any { + /* + $request ="http://api.crossref.org/works"."?filter="; + foreach($dois as $doi){ + $request.="doi:".urlencode( trim($doi)).","; + } + */ + var doisParams = ""; + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?",":"")+'doi:'+DOIs[i]; + } + let url = OpenaireProperties.getSearchCrossrefAPIURL()+'?filter='+doisParams; + let key = url; + + + return this.http.get(url) + .map(request => request.json().message) + .do(items => console.log("Crossref Results: total results = "+items['total-results']+" for doi = "+doisParams)); + //.catch(this.handleError); + + } + searchCrossrefByMultipleDOIs(dois: string[]):any { + let url = OpenaireProperties.getSearchCrossrefAPIURL()+'?filter=doi:'; + for(var i=0; i request.json().message) + .do(items => console.log("Crossref Results: total results = "+items['total-results'])); + //.catch(this.handleError); + + } + + 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.log(error); + return Observable.throw(error || 'Server error'); + } + +} diff --git a/claims/claim-utils/service/searchCrossrefService.module.ts b/claims/claim-utils/service/searchCrossrefService.module.ts new file mode 100644 index 00000000..798acdb3 --- /dev/null +++ b/claims/claim-utils/service/searchCrossrefService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchCrossrefService} from './searchCrossref.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchCrossrefService +], + exports: [ + ] +}) +export class SearchCrossrefServiceModule { } diff --git a/claims/claim-utils/service/searchDatacite.service.ts b/claims/claim-utils/service/searchDatacite.service.ts new file mode 100644 index 00000000..46b43032 --- /dev/null +++ b/claims/claim-utils/service/searchDatacite.service.ts @@ -0,0 +1,50 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +@Injectable() +export class SearchDataciteService { + constructor(private http: Http ) {} + + searchDataciteResults (term: string, size : number, page : number):any { + console.info("In search datacite results "+term); + let url = OpenaireProperties.getSearchDataciteAPIURL()+'?query='+term+'&rows='+size+'&start='+(size*(page-1)); + let key = url; + + return this.http.get( (OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(request => request.json()) + .do(items => console.info(items)) + .do(items => console.log("Datacite Results: total results = "+items.meta.total+" keyword = "+term)); + //.catch(this.handleError); + } + getDataciteResultByDOI (doi: string):any { + console.info("Fetch datacite resultt by DOI: "+doi); + let url = OpenaireProperties.getSearchDataciteAPIURL()+'/'+doi; + let key = url; + + return this.http.get( (OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(request => request.json()) + .do(items => console.info(items)); + // .do(items => console.log("Datacite Results: total results = "+items.meta.total+" doi = "+doi)) + + //.catch(this.handleError); + } + + + 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.log(error); + return Observable.throw(error || 'Server error'); + } + private extractData(res: Response) { + if (res.status < 200 || res.status >= 300) { + throw new Error('Bad response status: ' + res.status); + } + let body = res.json(); + return body.data || { }; + } +} diff --git a/claims/claim-utils/service/searchDataciteService.module.ts b/claims/claim-utils/service/searchDataciteService.module.ts new file mode 100644 index 00000000..659ca2e3 --- /dev/null +++ b/claims/claim-utils/service/searchDataciteService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchDataciteService} from './searchDatacite.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchDataciteService +], + exports: [ + ] +}) +export class SearchDataciteServiceModule { } diff --git a/claims/claim-utils/service/searchOrcid.service.ts b/claims/claim-utils/service/searchOrcid.service.ts new file mode 100644 index 00000000..0a60ef7a --- /dev/null +++ b/claims/claim-utils/service/searchOrcid.service.ts @@ -0,0 +1,126 @@ +import {Injectable} from '@angular/core'; +import {URLSearchParams} from '@angular/http'; +import {Http, Response} from '@angular/http'; +import { Headers, RequestOptions } from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + +@Injectable() +export class SearchOrcidService { + constructor( private http: Http ) {} + + + searchOrcidAuthor (term: string, authorIds: string[], + authorGivenNames: string[], authorFamilyNames: string[]):any { + console.info("In searchOrcidAuthor: "+term); + + var headers = new Headers(); + headers.append('Accept', 'application/orcid+json'); + + let url = OpenaireProperties.getSearchOrcidURL()+term+'/orcid-bio'; + let key = url; + + return this.http.get(url, { headers: headers }) + .map(res => res.json()['orcid-profile']) + .map(res => [res['orcid-bio']['personal-details']['given-names'], + res['orcid-bio']['personal-details']['family-name'], + res['orcid-identifier']]) + .map(res => this.parseOrcidAuthor(res, authorIds, authorGivenNames, authorFamilyNames)); + } + + searchOrcidAuthors (term: string, authorIds: string[], + authorGivenNames: string[], authorFamilyNames: string[]):any { + console.info("In search Orcid authors for keyword: "+term); + + var headers = new Headers(); + headers.append('Accept', 'application/orcid+json'); + + let url = OpenaireProperties.getSearchOrcidURL()+'search/orcid-bio?defType=edismax&q='+term+'&qf=given-name^1.0+family-name^2.0+other-names^1.0+credit-name^1.0&start=0&rows=10'; + let key = url; + + return this.http.get(url, { headers: headers }) + .map(res => res.json()['orcid-search-results']['orcid-search-result']) + .map(res => this.parseOrcidAuthors(res, authorIds, authorGivenNames, authorFamilyNames)); + + } + + searchOrcidPublications (id: string):any { + console.info("In search Orcid publications for author: "+id); + + var headers = new Headers(); + headers.append('Accept', 'application/orcid+json'); + + let url = OpenaireProperties.getSearchOrcidURL()+id+'/orcid-works'; + let key = url; + + return this.http.get(url, { headers: headers }) + .map(res => res.json()['orcid-profile']['orcid-activities']['orcid-works']); + //.map(res => res['orcid-work']); + } + + + parseOrcidAuthor (data: any, authorIds: string[], + authorGivenNames: string[], authorFamilyNames: string[]):any { + + if(data[2] != null) { + authorIds.push(data[2].path); + + if(data[0] != null) { + authorGivenNames.push(data[0].value); + } else { + authorGivenNames.push(""); + } + if(data[1] != null) { + authorFamilyNames.push(data[1].value); + } else { + authorFamilyNames.push(""); + } + + return true; + } + + return false; + } + + parseOrcidAuthors (data: any, authorIds: string[], + authorGivenNames: string[], authorFamilyNames: string[]):any { + let ret: boolean = false; + let mydata: any; + let length: number; + + if(data != null) { + length = data.length!=undefined ? data.length : 1; + + for(let i=0; i Clear All + + + `, + +}) +export class StartOverComponent { + constructor () { + + + } + ngOnInit() { + +} + + + // @Input() public inlineEntity = null; + @Input() public type:string; + @Input() public linkTo:string; + @Input() public results; + @Input() public projects; + @Input() public contexts; + + @ViewChild(AlertModal) alertApplyAll; + + confirmOpen(){ + this.alertApplyAll.cancelButton = true; + this.alertApplyAll.okButton = true; + this.alertApplyAll.alertTitle = "Remove selected"; + this.alertApplyAll.message = "This action will delete every selected entity (projects, communities, research results). Do you wish to continue?"; + this.alertApplyAll.okButtonText = "Yes"; + this.alertApplyAll.cancelButtonText = "No"; + this.alertApplyAll.open(); + } + confirmClose(data){ + this.startOver(); + } + startOver(){ + if(this.type != null && this.linkTo != null){ + console.log("inline"); + if(this.linkTo == "project"){ + this.projects.splice(0, this.projects.length); + }else if(this.linkTo == "context"){ + this.contexts.splice(0, this.contexts.length); + }else if(this.linkTo == "result"){ + this.results.splice(0, this.results.length); + } + }else{ + console.log("generic"); + this.results.splice(0, this.results.length); + this.projects.splice(0, this.projects.length); + this.contexts.splice(0, this.contexts.length); + } + console.log("projects:"+this.projects.length +" contexts:"+this.contexts.length + " results:"+this.results.length ); + } + +} diff --git a/claims/claim-utils/startOver.module.ts b/claims/claim-utils/startOver.module.ts new file mode 100644 index 00000000..bde3d0a2 --- /dev/null +++ b/claims/claim-utils/startOver.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { SharedModule } from '../../shared/shared.module'; +import { CommonModule } from '@angular/common'; +import {StartOverComponent} from './startOver.component'; +import {AlertModalModule} from '../../utils/modal/alertModal.module'; + + @NgModule({ + imports: [ + SharedModule, CommonModule, AlertModalModule + ], + declarations: [ + StartOverComponent + ], + exports: [StartOverComponent ] +}) +export class StartOverModule { } diff --git a/claims/claim.module.ts b/claims/claim.module.ts new file mode 100644 index 00000000..113e8597 --- /dev/null +++ b/claims/claim.module.ts @@ -0,0 +1,68 @@ +// import { NgModule} from '@angular/core'; +// import { CommonModule } from '@angular/common'; +// import { FormsModule } from '@angular/forms'; +// // +// import {UtilsModule} from '../utils/utils.module'; +// import {ServicesModule} from '../services/services.module'; +// +// import { ClaimsService} from '../services/claims.service'; +// //main +// import {ClaimComponent} from './claim/claim.component'; +// import {ClaimsAdminComponent} from './claims/claimsAdmin.component'; +// import {MyClaimsComponent} from './myClaims/myClaims.component'; +// import {LinkingHomeComponent} from './linking/linkingHome.component'; +// import {LinkingComponent} from './linking/linking.component'; +// import { BulkLinkingComponent } from './linking/bulkLinking.component'; +// +// import {BulkClaimComponent} from './linking/bulkClaim/bulkClaim.component'; +// import {ClaimsComponent} from './claim-utils/claims.component'; +// +// import {ClaimContextComponent} from './claim-utils/claimContext.component'; +// import {ClaimProjectsComponent} from './claim-utils/claimProject.component'; +// import {ClaimResultComponent} from './claim-utils/claimResult.component'; +// import {ClaimPublicationComponent} from './claim-utils/claimPublication.component'; +// import {ClaimDatasetComponent} from './claim-utils/claimDataset.component'; +// +// import {ClaimInsertComponent} from './linking/insertClaim/insertClaim.component'; +// +// import {ClaimSelectedContextsComponent} from './linking/selected/selectedContexts.component'; +// import {ClaimSelectedComponent} from './linking/selected/selected.component'; +// import {ClaimSelectedDatasetsComponent} from './linking/selected/selectedDatasets.component'; +// import {ClaimSelectedResultsComponent} from './linking/selected/selectedResults.component'; +// import {ClaimSelectedProjectsComponent} from './linking/selected/selectedProjects.component'; +// import {ClaimSelectedPublicationsComponent} from './linking/selected/selectedPublications.component'; +// +// import {LinkingGenericComponent} from './linking/linkingGeneric.component'; +// +// import {InlineClaimContextComponent} from './inlineClaims/inlineClaimContext.component'; +// import {InlineClaimProjectComponent} from './inlineClaims/inlineClaimProject.component'; +// import {InlineClaimResultComponent} from './inlineClaims/inlineClaimResult.component'; +// import {ClaimEntityFormatter} from '../utils/claimEntityFormatter.component'; +// +// import { Claim } from '../utils/entities/claim'; +// //helpers +// +// import { ClaimRoutingModule } from './claim-routing.module'; +// @NgModule({ +// imports: [ +// CommonModule, FormsModule, +// UtilsModule, +// ServicesModule, +// ClaimRoutingModule +// +// ], +// declarations: [ +// ClaimsAdminComponent, MyClaimsComponent, ClaimComponent, ClaimsComponent, +// BulkLinkingComponent, LinkingComponent, LinkingHomeComponent, LinkingGenericComponent, +// InlineClaimContextComponent, InlineClaimProjectComponent, InlineClaimResultComponent, ClaimSelectedComponent, +// ClaimContextComponent, ClaimSelectedContextsComponent, ClaimInsertComponent, ClaimProjectsComponent, ClaimSelectedProjectsComponent, +// ClaimResultComponent, ClaimSelectedPublicationsComponent, ClaimSelectedDatasetsComponent, ClaimSelectedResultsComponent, ClaimPublicationComponent, +// ClaimDatasetComponent, BulkClaimComponent, +// ClaimEntityFormatter +// ], +// providers: [ ClaimsService ], +// exports: [ +// InlineClaimContextComponent, InlineClaimProjectComponent, InlineClaimResultComponent +// ] +// }) +// export class ClaimModule { } diff --git a/claims/claimsAdmin/claimsAdmin-routing.module.ts b/claims/claimsAdmin/claimsAdmin-routing.module.ts new file mode 100644 index 00000000..f915d2e9 --- /dev/null +++ b/claims/claimsAdmin/claimsAdmin-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { AdminLoginGuard} from'../../login/adminLoginGuard.guard'; + +import { ClaimsAdminComponent } from './claimsAdmin.component'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: ClaimsAdminComponent, canActivate: [IsRouteEnabled, AdminLoginGuard], + data: {redirect: '/error'}, canDeactivate: [PreviousRouteRecorder]}]) + ] +}) +export class ClaimsAdminRoutingModule { } diff --git a/claims/claimsAdmin/claimsAdmin.component.ts b/claims/claimsAdmin/claimsAdmin.component.ts new file mode 100644 index 00000000..c498cc6f --- /dev/null +++ b/claims/claimsAdmin/claimsAdmin.component.ts @@ -0,0 +1,38 @@ +import {Component, ViewChild, Input} from '@angular/core'; +import {Location} from '@angular/common'; +import {Observable} from 'rxjs/Observable'; +import { Meta} from '../../../angular2-meta'; + +@Component({ + selector: 'claims-admin', + template: ` +
+
+
+ +
+
+
+
+
+ Claims Administrator +
+ +
+
+
+
+ + `, + +}) +export class ClaimsAdminComponent { + constructor ( private _meta: Meta ) { + this._meta.setTitle("OpenAIRE | Claims Administrator"); + } + ngOnInit() { + } +} diff --git a/claims/claimsAdmin/claimsAdmin.module.ts b/claims/claimsAdmin/claimsAdmin.module.ts new file mode 100644 index 00000000..947bc901 --- /dev/null +++ b/claims/claimsAdmin/claimsAdmin.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import { ClaimsAdminComponent } from './claimsAdmin.component'; +import { ClaimsAdminRoutingModule } from './claimsAdmin-routing.module'; +// import{ClaimServiceModule} from '../claim-utils/service/claimsService.module'; +import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.module'; +import { AdminLoginGuard} from'../../login/adminLoginGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + SharedModule, + ClaimsAdminRoutingModule, + // ClaimServiceModule, + DisplayClaimsModule + + ], + providers:[AdminLoginGuard, PreviousRouteRecorder,IsRouteEnabled], + declarations: [ + ClaimsAdminComponent + ] +}) +export class ClaimsAdminModule { } diff --git a/claims/claimsByToken/claimsByToken-routing.module.ts b/claims/claimsByToken/claimsByToken-routing.module.ts new file mode 100644 index 00000000..3d50376a --- /dev/null +++ b/claims/claimsByToken/claimsByToken-routing.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { LoginGuard} from'../../login/loginGuard.guard'; +import { ClaimsByTokenComponent } from './claimsByToken.component'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: ClaimsByTokenComponent, canActivate: [IsRouteEnabled, LoginGuard], + data: {redirect: '/error'}, canDeactivate: [PreviousRouteRecorder]}]) + ] +}) +export class ClaimsByTokenRoutingModule { } diff --git a/claims/claimsByToken/claimsByToken.component.ts b/claims/claimsByToken/claimsByToken.component.ts new file mode 100644 index 00000000..bab35bb1 --- /dev/null +++ b/claims/claimsByToken/claimsByToken.component.ts @@ -0,0 +1,433 @@ +import {Component, ViewChild, Input} from '@angular/core'; +import {Location} from '@angular/common'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Params} from '@angular/router'; +import {ClaimsByTokenService} from './claimsByToken.service'; + +import {ModalSelect} from '../../utils/modal/selectModal.component'; +import {ModalLoading} from '../../utils/modal/loading.component'; + +import {Session} from '../../login/utils/helper.class'; + +import {RouterHelper} from '../../utils/routerHelper.class'; +import { Meta} from '../../../angular2-meta'; +import {ClaimsDatatablePipe} from '../../utils/pipes/claimsDatatable.pipe'; + +//import {DataTable} from "angular2-datatable"; + +@Component({ + selector: 'claims-project-manager', + template: ` +
+
+
+
+ + +
+
+ + +

Oops! Your email does not give you the authority to view claims for the selected project. Please contact the administrators.

+
+
+ +
+
+ Claims Administrator + + {{project['name']}} ({{project['funderName']}}) + + +
+

Pending Claims

+ +
+
No pending claims found.
+
+ +
+ +
+
+ +
+
+ + + {{totalPendingResults.count}} pending claims, page {{activePendingPage.page}} of {{totalPages(totalPendingResults.count)}} + + + + + + + + + + + + + + + + + + + + + +
Research ResultClaimed ByClaimed DateApprove
{{claim1.userMail}}{{claim1.date}} + + + +
+
+ +
*Note that claims you did not approved or disapproved are considered as right (but not curated)
+ + +

Already Curated Claims

+ +
+
No curated claims found.
+
+ +
+ +
+
+ +
+
+ + + {{totalCuratedResults.count}} curated claims, page {{activeCuratedPage.page}} of {{totalPages(totalCuratedResults.count)}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Research ResultClaimed byClaimed DateCurated byCuration DateApproved
{{claim.userMail}}{{claim.date}}{{claim.curatedBy}}{{claim.curationDate}} + + + + + +
+
+ + + +
+ +
+
+
+
+ `, + +}) +export class ClaimsByTokenComponent { + public token: string = ""; + public sub: any; + public project: any; + private claims:any = []; + public pending_claims: any = []; + public curated_claims: any = []; + public selectedRight: Set; + public selectedWrong: Set; + public editable: Set; + public contact_person: string[] = ["Konstantina", "Argiro", "Katerina"]; + + // when 'valid' show proper claims, when 'invalid' show no matched entry-wanna retry + public accessStatus: string;// = "empty"; + + public rowsOnPage = 5; + public sortOrder = "asc"; + public filterQuery:string = ""; + public filterQuery2:string = ""; + + public activePendingPage:any = {page: 1}; + public totalPendingResults:any = {count: 0}; + public activeCuratedPage:any = {page: 1}; + public totalCuratedResults:any = {count: 0}; + + + @ViewChild('mf1') table1: any;//DataTable; + @ViewChild('mf2') table2: any;//DataTable; + @ViewChild('filtered1') filteredItems1; + + + @ViewChild (ModalSelect) selectModal : ModalSelect; + @ViewChild (ModalLoading) loading : ModalLoading ; + + public routerHelper:RouterHelper = new RouterHelper(); + + constructor ( private route: ActivatedRoute, private claimsByTokenService: ClaimsByTokenService, private _meta: Meta) { + + } + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + this.token = params['token']; + this.selectedRight = new Set(); + this.selectedWrong = new Set(); + this.editable = new Set(); + //this.openSelect(); + //this.setMessageSelect("Please select your identity:"); + //this.setOptionsSelect(this.contact_person); + this.validateJWTandToken(); + this.updateTitle("Claims For Project Managers"); + } + ); + } + +refreshTable(table:any, $event:any, whichTable: string) { + if(whichTable == "pending") { + this.activePendingPage.page = $event.value; + } else if(whichTable == 'curated') { + this.activeCuratedPage.page = $event.value; + } + table.mfActivePage=$event.value; + table.setPage(table.mfActivePage, this.rowsOnPage); +} + +public sortByClaimDate1 = (claim: any) => { + return new Date(claim.date); +} + +public sortByCurationDate1 = (claim: any) => { + return new Date(claim.curationDate); +} + +public sortByTitle1 = (claim: any) => { + if(claim.targetType != 'project') { + return claim.target.title; + } else { + return claim.source.title; + } +} + +public sortByClaimDate2 = (claim: any) => { + return new Date(claim.date); +} + +public sortByCurationDate2 = (claim: any) => { + console.info(new Date(claim.curationDate)); + return new Date(claim.curationDate); +} + +public sortByTitle2= (claim: any) => { + if(claim.targetType != 'project') { + return claim.target.title; + } else { + return claim.source.title; + } +} + + + validateJWTandToken() { + var jwtToken=Session.getUserJwt(); + if(this.token) { + this.claimsByTokenService.getClaims(this.token, jwtToken).subscribe( + data => { + this.closeLoading(); + this.accessStatus = "valid"; + //console.info(data); + this.claims = data.data; + for(let claim of this.claims) { + if(claim.targetType == "project") { + this.project = claim.target; + } else { + this.project = claim.source; + } + if(claim.curatedBy) { + this.curated_claims.push(claim); + } else { + this.pending_claims.push(claim); + } + } + + this.totalPendingResults.count = this.pending_claims.length; + this.totalCuratedResults.count = this.curated_claims.length; + + this.updateTitle("Claims For Project Managers - "+this.project.name); + }, + err => { + this.accessStatus = "invalid"; + console.log(err); + } + ); + } else { + this.accessStatus = "invalid"; + } + } + + selectApprove(id:string, event) { + var value = event.currentTarget.checked; + if(value){ + this.selectedRight.add(id); + this.selectedWrong.delete(id); + console.info(this.selectedRight); + }else{ + this.selectedRight.delete(id); + console.info(this.selectedRight); + } + } + + selectDisapprove(id:string,event) { + var value = event.currentTarget.checked; + if(value){ + this.selectedWrong.add(id); + this.selectedRight.delete(id); + }else{ + this.selectedWrong.delete(id); + } + } + + isSelectedRight(id:string) { + return this.selectedRight.has(id); + } + + isSelectedWrong(id:string) { + return this.selectedWrong.has(id); + } + + isRight(claim: any) { + //claim.approved = true; + if(this.isSelectedRight(claim.id)) { + return true; + } else if(claim.approved == true && !this.isSelectedWrong(claim.id)) { + return true; + } + + return false; + } + + isWrong(claim: any) { + if(this.isSelectedWrong(claim.id)) { + return true; + } else if(claim.approved == false && !this.isSelectedRight(claim.id)) { + return true; + } + + return false; + } + + saveChanges() { + console.info("Changes Saved!"); + var jwtToken=Session.getUserJwt(); + + this.claimsByTokenService.updateClaimsCuration(this.selectedRight, this.selectedWrong).subscribe( + data => { + console.info(data); + }, + err => { + console.log(err); + } + ); + + } + + public closeLoading(){ + if(this.loading){ + this.loading.close(); + } + } + + curatorSelected(selected: string) { + console.info("selected curator: "+selected); + } + + public openSelect(){ + if(this.selectModal){ + this.selectModal.open(); + } + } + + public setMessageSelect(message: string){ + if(this.selectModal){ + this.selectModal.message = message; + } + } + + public setOptionsSelect(options: string[]){ + if(this.selectModal){ + this.selectModal.options = options; + } + } + + totalPages(totalResults: number): number { + let totalPages:any = totalResults/(this.rowsOnPage); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + return totalPages; + } + + updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + } + +} diff --git a/claims/claimsByToken/claimsByToken.module.ts b/claims/claimsByToken/claimsByToken.module.ts new file mode 100644 index 00000000..9f5827b5 --- /dev/null +++ b/claims/claimsByToken/claimsByToken.module.ts @@ -0,0 +1,49 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import {DataTableModule} from "angular2-datatable"; + +import { SharedModule } from '../../shared/shared.module'; +import { ClaimsByTokenComponent } from './claimsByToken.component'; +import { ClaimsByTokenService } from './claimsByToken.service'; +import { ClaimsByTokenRoutingModule } from './claimsByToken-routing.module'; +import {ClaimEntityFormatterModule} from '../claim-utils/entityFormatter/claimEntityFormatter.module'; +// import{ClaimServiceModule} from '../claim-utils/service/claimsService.module'; +//import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.module'; +import {SelectModalModule} from '../../utils/modal/selectModal.module'; +import {LoadingModalModule} from '../../utils/modal/loadingModal.module'; + +import {LoginGuard} from'../../login/loginGuard.guard'; + +import {PagingModule} from '../../utils/paging.module'; +import {ClaimsDatatablePipe} from '../../utils/pipes/claimsDatatable.pipe'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + + +@NgModule({ + imports: [ + RouterModule, + DataTableModule, + SharedModule, + ClaimsByTokenRoutingModule, + ClaimEntityFormatterModule, + SelectModalModule, + LoadingModalModule, + PagingModule + // ClaimServiceModule, + //DisplayClaimsModule + + ], + providers:[ + ClaimsByTokenService, + LoginGuard, PreviousRouteRecorder, IsRouteEnabled + ], + declarations: [ + ClaimsByTokenComponent, ClaimsDatatablePipe + ], + exports: [ + ClaimsByTokenComponent, ClaimsDatatablePipe + ] +}) +export class ClaimsByTokenModule { } diff --git a/claims/claimsByToken/claimsByToken.service.ts b/claims/claimsByToken/claimsByToken.service.ts new file mode 100644 index 00000000..ab75c85a --- /dev/null +++ b/claims/claimsByToken/claimsByToken.service.ts @@ -0,0 +1,77 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Jsonp, URLSearchParams,ResponseOptions, RequestOptions, Headers} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/operator/do'; + +import { CustomOptions } from '../claim-utils/service/customOptions.class'; + +@Injectable() +export class ClaimsByTokenService { + + constructor(private http: Http ) {} + + getClaims(token: string, jwtToken: string):any { + console.info("getClaims in service"); + + let url = OpenaireProperties.getClaimsAPIURL()+"project/claims?projectToken="+token; + + let key = url; + + return this.http.get(url, CustomOptions.getAuthOptions()) + //.map(res => res.text()) + .map(request => request.json()); + + } + + +/* + getClaims(email: string, token: string, user_token: string):any { + let url = OpenaireProperties.getClaimsAPIURL(); // What else? + let body = JSON.stringify( {"email": email, "token": token} ); + console.warn('Json body: : '+body); + let headers = new Headers({ 'Content-Type': 'application/json' }); + let options = new RequestOptions({ headers: headers }); + return this.http.post(url, body, options) + .map(res => res.json()) + .do(request => console.info("Insert Response:"+request.status) ) + .catch(this.handleError); + } +*/ + + updateClaimsCuration( selectedRight: Set, selectedWrong: Set) { + let url = OpenaireProperties.getClaimsAPIURL() + "curate/bulk"; + let claimsCurationInfo: any = []; //e.g.: [{"id":"2","approved":true},{"id":"1","approved":true}] + + selectedRight.forEach(function(selected) { + console.info(selected); + let claimCurationInfo: {"id": string, "approved": boolean} = {"id": selected, "approved": true}; + claimsCurationInfo.push(claimCurationInfo); + }); + + selectedWrong.forEach(function(selected) { + let claimCurationInfo: any = {"id": selected, "approved": false}; + claimsCurationInfo.push(claimCurationInfo); + }); + + console.info("\n\n"+claimsCurationInfo); + + + let body = JSON.stringify( claimsCurationInfo ); + console.warn('Json body: : '+body); + let headers = new Headers({ 'Content-Type': 'application/json' }); + let options = new RequestOptions({ headers: headers }); + return this.http.post(url, body, CustomOptions.getAuthOptionsWithBody()) + .map(res => res.json()) + .do(request => console.info("Insert Response:"+request.status) ) + .catch(this.handleError); + } + + 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.log(error); + return Observable.throw(error || 'Server error'); + } +} diff --git a/claims/directLinking/directLinking-routing.module.ts b/claims/directLinking/directLinking-routing.module.ts new file mode 100644 index 00000000..e9ed1f35 --- /dev/null +++ b/claims/directLinking/directLinking-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { LoginGuard} from'../../login/loginGuard.guard'; + +import { DirectLinkingComponent } from './directLinking.component'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: DirectLinkingComponent, canActivate: [IsRouteEnabled, LoginGuard], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder]}, + + ]) + ] +}) +export class DirectLinkingRoutingModule { } diff --git a/claims/directLinking/directLinking.component.html b/claims/directLinking/directLinking.component.html new file mode 100644 index 00000000..5dab8ae8 --- /dev/null +++ b/claims/directLinking/directLinking.component.html @@ -0,0 +1,135 @@ +
+
+
+ +
+
+ Link +
+
+ +
+
+ +
+ +
+ +
    +
  • +

    + + {{(projects.length + contexts.length + results.length)}} +

    +
    + + + + + +
    +
  • +
+ +
+ Link {{(type=="project")?'Project':' Research result'}}: +
+
+ +
+ +
+
+
+ {{displayedResult.title}} + {{displayedResult.title}} +
+ + +
+ +
+ +
+ {{projects[0].funderName}} | {{projects[0].projectName}} {{(projects[0].projectAcronym)?'('+projects[0].projectAcronym+')':''}} + +
+ + + +
+ + + + + + + +
+
+ + +
+ +
+
+ + + +
+
+ +
+ +
+
+
+
diff --git a/claims/directLinking/directLinking.component.ts b/claims/directLinking/directLinking.component.ts new file mode 100644 index 00000000..8df535bb --- /dev/null +++ b/claims/directLinking/directLinking.component.ts @@ -0,0 +1,208 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; +import {EntitiesSearchService} from '../../utils/entitiesAutoComplete/entitySearch.service'; +import {ClaimProject, ClaimResult} from '../claim-utils/claimEntities.class'; +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import {SearchDatasetsService} from '../../services/searchDatasets.service'; +import {SearchSoftwareService} from '../../services/searchSoftware.service'; + +import { Meta} from '../../../angular2-meta'; + +@Component({ + selector: 'directLinking', + templateUrl: 'directLinking.component.html' +}) +export class DirectLinkingComponent { + contexts=[]; + projects=[]; + + results = []; + + linkType:string ="project"; // link type (selected in home page) : project, context, software, etc + /* url Parameters for inline linking */ + id:string = null; //entity id + type:string = null; // entity type (publication or dataset) + linkTo:string = null; // entity type (project or context or result) + + entityTypes=["dataset", "publication","software", "project","context"]; + inlineResult:ClaimResult =null; + displayedResult:ClaimResult =null; + sub:any =null; + show:string="claim"; //{claim,result} + validInput:boolean = null;//'true; + constructor ( private _router: Router, private route: ActivatedRoute, private entitySearch:EntitiesSearchService, + private publicationsSearch:SearchPublicationsService, private datasetsSearch:SearchDatasetsService, private softwareSearch:SearchSoftwareService, private _meta: Meta) { + this._meta.setTitle("OpenAIRE | Direct Linking"); + } + ngOnInit() { + if(localStorage.getItem("projects")){ + this.projects = JSON.parse(localStorage.getItem("projects")); + } + if(localStorage.getItem("contexts")){ + this.contexts = JSON.parse(localStorage.getItem("contexts")); + } + if(localStorage.getItem("results")){ + this.results = JSON.parse(localStorage.getItem("results")); + } + if(localStorage.getItem("inlineEntity")){ + this.inlineResult = JSON.parse(localStorage.getItem("inlineEntity")); + } + + localStorage.removeItem("projects"); + localStorage.removeItem("contexts"); + localStorage.removeItem("results"); + localStorage.removeItem("inlineEntity"); + + this.sub = this.route.queryParams.subscribe(params => { + this.id = params['id']; + this.type = params['type']; + this.linkTo = params['linkTo']; + if(this.type!=null && this.linkTo!=null){ + this.type = (this.entityTypes.indexOf(this.type) != -1)? this.type:'publication'; + this.linkTo = (this.entityTypes.indexOf(this.linkTo) != -1 || this.linkTo == "result")? this.linkTo:'project'; + this.show = (this.linkTo != "result")?"claim":"result"; + this.linkType = this.linkTo; + var isInlineResult:boolean = false; // is a link result - result + // if((this.type == "publication" || this.type == "dataset" || this.type == "software") && ((this.linkTo == "publication" || this.linkTo == "dataset" || this.linkTo == "software") || this.linkTo == "result" )){ + // isInlineResult = true; + // } + if(this.type == "project"){ + this.linkType = "project"; + this.getProjectById(this.id); + }else if(this.type == "publication"){ + this.getPublicationById(this.id,true); + }else if(this.type == "dataset"){ + this.getDatasetById(this.id,true); + }else if(this.type == "software"){ + this.getSoftwareById(this.id,true); + }else{ + this.validInput = this.isValidInput(null); + } + + }else{ + this.validInput = this.isValidInput(null); + + } + + }); + } + isValidInput(result){ + if(result == null){ + return false; + }else if(this.type == "project" && this.linkTo != "result"){ + return false; + }else if(["dataset","publication","software"].indexOf(this.type) != -1 && (["project","context","result"].indexOf(this.linkTo) == -1)){ + return false; + }else if(["project","dataset","publication","software"].indexOf(this.type) == -1){ + return false; + }else{ + return true; + } + } + getProjectById(id:string){ + this.sub = this.entitySearch.fetchByType(id,"project").subscribe( + data => { + console.log(data); + var item =data[0]; + var project: ClaimProject = new ClaimProject(); + project.funderId = item.funderId; + project.funderName = item.funderName; + project.projectId = id; + project.projectName = item.projectName; + project.projectAcronym = item.projectAcronym; + project.startDate = item.startDate; + project.endDate = item.endDate; + project.code = item.code; + project.jurisdiction = item.jurisdiction; + project.fundingLevel0 = item.fundingLevel0; + + this.projects.push( project); + this.validInput = this.isValidInput(project); + + }, + err => { + this.validInput = this.isValidInput(null); + console.log("An error occured") + }); + } + getPublicationById(id:string, isInlineResult:boolean){ + + this.sub = this.publicationsSearch.searchPublicationById(id).subscribe( + data => { + var item =data[0]; + var result: ClaimResult = new ClaimResult(); + result.id=id; + result.type="publication"; + result.source="openaire"; + result.title = item['title'].name; + result.url= item['title'].url; + result.result = item; + result.accessRights = item['title'].accessMode; + result.date = item.year; + this.displayedResult = result; + if(isInlineResult){ + this.inlineResult = result; + }else{ + this.results.push( result); + } + this.validInput = this.isValidInput(result); + }, + err => { + this.validInput = this.isValidInput(null); + console.log("An error occured") + }); + } + getDatasetById(id:string, isInlineResult:boolean){ + this.sub = this.datasetsSearch.searchDatasetById(id).subscribe( + data => { + var item =data[0]; + var result: ClaimResult = new ClaimResult(); + result.id=id; + result.type="dataset"; + result.source="openaire"; + result.title = item['title'].name; + result.url= item['title'].url; + result.result = item; + result.accessRights = item['title'].accessMode; + result.date = item.year; + this.displayedResult = result; + if(isInlineResult){ + this.inlineResult = result; + }else{ + this.results.push( result); + } + this.validInput = this.isValidInput(result); + }, + err => { + this.validInput = this.isValidInput(null); + console.log("An error occured") + }); + } + getSoftwareById(id:string, isInlineResult:boolean){ + this.sub = this.softwareSearch.searchSoftwareById(id).subscribe( + data => { + var item =data[0]; + var result: ClaimResult = new ClaimResult(); + result.id=id; + result.type="software"; + result.source="openaire"; + result.title = item['title'].name; + result.url= item['title'].url; + result.result = item; + result.accessRights = item['title'].accessMode; + result.date = item.year; + this.displayedResult = result; + if(isInlineResult){ + this.inlineResult = result; + }else{ + this.results.push( result); + } + this.validInput = this.isValidInput(result); + }, + err => { + this.validInput = this.isValidInput(null); + console.log("An error occured") + }); +} +} diff --git a/claims/directLinking/directLinking.module.ts b/claims/directLinking/directLinking.module.ts new file mode 100644 index 00000000..742d548d --- /dev/null +++ b/claims/directLinking/directLinking.module.ts @@ -0,0 +1,40 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import { DirectLinkingComponent } from './directLinking.component'; +import { DirectLinkingRoutingModule } from './directLinking-routing.module'; + +import {SelectedProjectsModule} from '../linking/selected/selectedProjects.module'; +import {SelectedContextsModule} from '../linking/selected/selectedContexts.module'; +import {SelectedPublicationsModule} from '../linking/selected/selectedResults.module'; +import {InsertClaimsModule} from '../linking/insertClaim/insertClaim.module'; +import {StartOverModule} from '../claim-utils/startOver.module'; + +import {EntitySearchServiceModule} from '../../utils/entitiesAutoComplete/entitySearchService.module'; +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import {SoftwareServiceModule} from '../../services/softwareService.module'; +import {LoginGuard} from'../../login/loginGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {HelperModule} from '../../utils/helper/helper.module'; +import {ClaimContextSearchFormModule} from '../claim-utils/claimContextSearchForm.module'; +import {ClaimProjectsSearchFormModule} from '../claim-utils/claimProjectSearchForm.module'; +import {ClaimResultSearchFormModule} from '../claim-utils/claimResultSearchForm.module'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + + +@NgModule({ + imports: [ + SharedModule, + DirectLinkingRoutingModule,SelectedProjectsModule, SelectedContextsModule, SelectedPublicationsModule, InsertClaimsModule, + EntitySearchServiceModule, PublicationsServiceModule, DatasetsServiceModule, StartOverModule, HelperModule, + ClaimContextSearchFormModule, ClaimProjectsSearchFormModule, ClaimResultSearchFormModule + + + ], + providers:[LoginGuard, PreviousRouteRecorder, IsRouteEnabled], + declarations: [ + DirectLinkingComponent + ], exports:[DirectLinkingComponent] +}) +export class DirectLinkingModule { } diff --git a/claims/linking/bulkClaim/bulkClaim.component.ts b/claims/linking/bulkClaim/bulkClaim.component.ts new file mode 100644 index 00000000..bc9ea125 --- /dev/null +++ b/claims/linking/bulkClaim/bulkClaim.component.ts @@ -0,0 +1,256 @@ +import {Component, Input, Output, EventEmitter,ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {SearchCrossrefService} from '../../claim-utils/service/searchCrossref.service'; +import {SearchDataciteService} from '../../claim-utils/service/searchDatacite.service'; + +import {ModalLoading} from '../../../utils/modal/loading.component'; +import {Dates, DOI} from '../../../utils/string-utils.class'; +import {OpenaireProperties} from '../../../utils/properties/openaireProperties'; +import {ClaimResult} from '../../claim-utils/claimEntities.class'; + + +@Component({ + selector: 'bulk-claim', + template: ` +
+
+ + + + + + + +
Upload a DOI csv file:
+ + + + + + + +
+ + + +
+ ` + +}) +//[(ngModel)]="date" +export class BulkClaimComponent { + filesToUpload: Array; + navigateTo: string = "Search"; + source: string = "crossref"; + type : string = "publication"; + resultsFromSearch:number; + @Input() public select:boolean = true ; + @Input() public results; + + allIds:string[] = []; + foundIds:string[] = []; + duplicateIds:string[] = []; + notFoundIds:string[] = []; + noValidIds:string[] = []; + showReport:boolean = false; + showInfo :boolean = false; + @ViewChild (ModalLoading) loading : ModalLoading ; + errorMessage = ""; + infoMEssage = ""; + enableUpload:boolean = true; + constructor(private _searchCrossrefService: SearchCrossrefService, private _searchDataciteService: SearchDataciteService) { + this.filesToUpload = []; + } + ngOnInit() {} + + upload() { + this.enableUpload = false; + this.showReport = false; + this.errorMessage = ""; + if(this.filesToUpload.length == 0){ + this.errorMessage = "There is no selected file to upload."; + return ; + } + this.loading.open(); + + this.makeFileRequest(OpenaireProperties.getUploadServiceUrl(), [], this.filesToUpload).then((result) => { + var rows = (result as any).split('\n'); // I have used space, you can use any thing. + var i = 0; + this.duplicateIds = []; + this.allIds = []; + this.foundIds = []; + this.noValidIds = []; + this.results.slice(0,this.results.length); + this.notFoundIds = []; + + for(i=0;i-1){ + this.duplicateIds.push(id); + }else{ + this.allIds.push(id); + this.fetchResult(id,accessMode,embargoDate); + } + }else{ + this.noValidIds.push(id); + } + } + + } + + }, (error) => { + this.enableUpload = true; + console.log(error); + this.loading.close(); + this.errorMessage = "An error occured while uploading..."; + }); + } + private removeDoubleQuotes(value){ + if(value.indexOf('"')== 0){ + value = value.substring(1,value.length); + } + var index =+value.indexOf('"'); + if(index == (value.length - 1) || index == (value.length - 2) ){ + value = value.substring(0,index); + } + return value; + } + private validateAccessMode(value){ + var accessModes = ["OPEN", "CLOSED", "EMBARGO"]; + if(accessModes.indexOf(value) > -1){ + return true; + } + + return false; + } + + fileChangeEvent(fileInput: any){ + this.filesToUpload = > fileInput.target.files; + } + + makeFileRequest(url: string, params: Array, files: Array) { + return new Promise((resolve, reject) => { + var formData: any = new FormData(); + var xhr = new XMLHttpRequest(); + for(var i = 0; i < files.length; i++) { + formData.append("uploads[]", files[i], files[i].name); + } + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + if (xhr.status == 200) { + resolve(xhr.response); + } else { + reject(xhr.response); + } + } + } + xhr.open("POST", url, true); + xhr.send(formData); + }); + } + + fetchResult(id:string,accessMode:string,date:string){ + this._searchCrossrefService.searchCrossrefByDOIs([id]).subscribe( + data => { + + var crossrefResult = data.items[0]; + if(data.items.length > 0){ + this.foundIds.push(id); + var result: ClaimResult = ClaimResult.generateResult(crossrefResult, id,"crossref","publication", crossrefResult.URL, crossrefResult.title, crossrefResult.created['date-time'], accessMode); + result.embargoEndDate = date; + this.results.push(result); + this.endOfFetching(); + }else{ + this.searchInDatacite(id,accessMode,date); + // this.notFoundIds.push(id); + } + }, + err => { + console.log(err); + this.notFoundIds.push(id); + this.endOfFetching(); + } + ); + } + searchInDatacite(id:string,accessMode:string,date:string){ + this._searchDataciteService.getDataciteResultByDOI(id).subscribe( + item => { + var dataciteResult = item.data; + + if(dataciteResult != null && dataciteResult.attributes!= null ){ + + this.foundIds.push(id); + var result: ClaimResult = ClaimResult.generateResult(dataciteResult, id,"datacite","dataset", 'http://dx.doi.org/'+dataciteResult.attributes.doi, dataciteResult.attributes.title, dataciteResult.attributes.published, accessMode); + result.embargoEndDate = date; + this.results.push(result); + }else{ + this.notFoundIds.push(id); + } + this.endOfFetching(); + }, + err => { + console.log(err); + this.notFoundIds.push(id); + this.endOfFetching(); + } + ); + } + endOfFetching(){ + if(this.allIds.length == this.foundIds.length+this.notFoundIds.length+ this.duplicateIds.length ){ + this.showReport = true; + this.enableUpload = true; + this.loading.close(); + + } + + } +} diff --git a/claims/linking/bulkClaim/bulkClaim.module.ts b/claims/linking/bulkClaim/bulkClaim.module.ts new file mode 100644 index 00000000..7f35a46f --- /dev/null +++ b/claims/linking/bulkClaim/bulkClaim.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../../shared/shared.module'; +import {LoadingModalModule} from '../../../utils/modal/loadingModal.module'; +import {BulkClaimComponent} from './bulkClaim.component'; +import {SearchCrossrefServiceModule} from '../../claim-utils/service/searchCrossrefService.module'; +import {SearchDataciteServiceModule} from '../../claim-utils/service/searchDataciteService.module'; + +@NgModule({ + imports: [ + SharedModule, LoadingModalModule, SearchCrossrefServiceModule + ], + declarations: [ +BulkClaimComponent + ], exports:[ BulkClaimComponent] +}) +export class BulkClaimModule { } diff --git a/claims/linking/bulkLinking.component.ts b/claims/linking/bulkLinking.component.ts new file mode 100644 index 00000000..96e32dcf --- /dev/null +++ b/claims/linking/bulkLinking.component.ts @@ -0,0 +1,16 @@ +// import {Component, Input} from '@angular/core'; +// import {Observable} from 'rxjs/Observable'; +// +// @Component({ +// selector: 'bulk-linking', +// //providers: [MdRadioDispatcher], +// template: ` +// +// ` +// +// }) +// //[(ngModel)]="date" +// export class BulkLinkingComponent { +// constructor () { +// } +// } diff --git a/claims/linking/bulkLinking.module.ts b/claims/linking/bulkLinking.module.ts new file mode 100644 index 00000000..55c71221 --- /dev/null +++ b/claims/linking/bulkLinking.module.ts @@ -0,0 +1,20 @@ +// import { NgModule } from '@angular/core'; +// +// import { SharedModule } from '../../shared/shared.module'; +// import { BulkLinkingComponent } from './bulkLinking.component'; +// import { BulkLinkingRoutingModule } from './bulkLinking-routing.module'; +// import {LinkingGenericModule} from './linkingGeneric.module'; +// import {BulkClaimModule} from './bulkClaim/bulkClaim.module'; +// @NgModule({ +// imports: [ +// SharedModule, +// BulkLinkingRoutingModule, +// LinkingGenericModule, +// BulkClaimModule +// +// ], +// declarations: [ +// BulkLinkingComponent +// ], exports:[BulkLinkingComponent] +// }) +// export class BulkLinkingModule { } diff --git a/claims/linking/insertClaim/insertClaim.component.ts b/claims/linking/insertClaim/insertClaim.component.ts new file mode 100644 index 00000000..faea79ff --- /dev/null +++ b/claims/linking/insertClaim/insertClaim.component.ts @@ -0,0 +1,371 @@ +import {Component, Input, Output, EventEmitter, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {Router} from '@angular/router'; +import {ClaimsService} from '../../claim-utils/service/claims.service'; + +import {ModalLoading} from '../../../utils/modal/loading.component'; +import {AlertModal} from '../../../utils/modal/alert'; +import {Md5} from 'ts-md5/dist/md5'; +import {Session} from '../../../login/utils/helper.class'; +import {ErrorCodes} from '../../../login/utils/guardHelper.class'; + +@Component({ + selector: 'claim-insert', + template: ` +
+ +
There are {{insertedClaims.length}} claims, follow the link to manage your claims
+
+
+ +
+ + + + + + + ` +}) +export class ClaimInsertComponent { + constructor (private claimService: ClaimsService, private _router:Router) {} + ngOnInit() { + // console.info("Inlineentity:" +(this.inlineEntity)?this.inlineEntity+(this.inlineEntity.id)?this.inlineEntity.id:"no id":"null"+ + " show "+ (!this.claiming && this.showButton) ); + } + + + @Input() public contexts; + @Input() public projects; + @Input() public results; + @Input() public showButton:boolean = true; + @Input() show='claim'; + @Input() inlineEntity = null; // the entity from the landing page + @Output() showChange = new EventEmitter(); + + @ViewChild (ModalLoading) loading : ModalLoading ; + @ViewChild(AlertModal) alert; + + public claiming =false; + public error = false; + public errorMessage = ""; + public warningMessage = ""; + public claimsTODO:number = 0; + public claims:number = 0; + + private servicesRespond:number = 0; + private insertedClaims=[]; + private errorInClaims=[]; + private insertedRecords=[]; + private errorInRecords=[]; +public validateInsertions(){ + // console.info("Inlineentity:" +(this.inlineEntity)?this.inlineEntity+(this.inlineEntity.id)?this.inlineEntity.id:"no id":"null"+ + " show "+ (!this.claiming && this.showButton) ); + if(this.validate()){ + if(this.validateDates()){ + this.insertActions(); + return true; + } + } + return +} +private insertActions(){ + this.servicesRespond = 0; + this.insertedClaims=[]; + this.errorInClaims=[]; + this.insertedRecords=[]; + this.errorInRecords=[]; + if(!Session.isValidAndRemove()){ + this.showButton = false; + localStorage.setItem("projects", JSON.stringify(this.projects)); + localStorage.setItem("contexts", JSON.stringify(this.contexts)); + localStorage.setItem("results", JSON.stringify(this.results)); + if(this.inlineEntity != null){ + localStorage.setItem("inlineEntity", JSON.stringify(this.inlineEntity)); + } + + this._router.navigate(['/user-info'], { queryParams: { "errorCode": ErrorCodes.NOT_VALID, "redirectUrl": this._router.url} }); + + }else{ + this.claiming = true; + var user=Session.getUserEmail(); + this.loading.open(); + var claims = []; + var directclaims = []; + if(this.results){ + console.info("results: "+this.results.length); + + for (var i = 0; i < this.results.length; i++) { + var result=this.results[i]; + if(["crossref","datacite","orcid"].indexOf(result.source) != -1){ + directclaims.push({"id":result.id, "record":this.createDirectClaim(result,this.projects,this.contexts)}); + } + if(this.contexts){ + for (var j = 0; j < this.contexts.length; j++) { + var context = this.contexts[j]; + var claim = this.createContextClaim(result, context, user); + claims.push(claim); + } + } + if(this.projects){ + for (var k = 0; k < this.projects.length; k++) { + var project = this.projects[k]; + var projectClaim = this.createProjectClaim(result, project, user); + claims.push(projectClaim); + } + } + if(this.inlineEntity != null){ + var resultClaim = this.createResultClaim(this.inlineEntity, result, user); + claims.push(resultClaim); + } + + } + } + //first call direct index service - when call is done (success or error) call isertBulkClaims method to insert claims in DB + console.info("\n\ndirectclaims: "+directclaims.length+"\n\n"); + if(directclaims.length > 0){ + this.claimService.insertDirectRecords(directclaims).subscribe( + data => { + this.insertedRecords = data.insertedIds; + + this.errorInRecords = data.errorInClaims; + this.isertBulkClaims(claims); + }, + err => { + err=err.json(); + if(err.insertedIds && err.insertedIds.length >0){ + this.insertedRecords = err.insertedIds; + } + if(err.errorInClaims && err.errorInClaims.length >0){ + this.errorInRecords = err.errorInClaims; + } + this.isertBulkClaims(claims); + } + ); + }else{ + this.isertBulkClaims(claims); + } + } + +} + +private isertBulkClaims(claims){ + console.info("try to insert "+claims.length+" claims"); + this.claimService.insertBulkClaims(claims).subscribe( + data => { + this.insertedClaims = data.insertedIds; + this.errorInClaims = data.errorInClaims; + this.afterclaimsInsertion(); + }, + err => { + err=err.json(); + if(err.insertedIds && err.insertedIds.length >0){ + this.insertedClaims = err.insertedIds; + } + if(err.errorInClaims && err.errorInClaims.length >0){ + this.errorInClaims = err.errorInClaims; + } + this.afterclaimsInsertion(); + } + ); +} +private validate(){ + this.warningMessage = ""; + this.errorMessage = ""; + if( this.results && this.results.length == 0){ + this.warningMessage = "There are no research results selected."; + }else if((!this.contexts|| this.contexts.length==0 )&&(!this.projects|| this.projects.length==0 )&& ( this.inlineEntity == null)){ + this.warningMessage = "There are no projects or communities to link."; + // }else if (this.inline && !this.inlineEntity){ + // this.errorMessage = "No inline entity"; + // console.log(this.inline + " "+ this.inlineEntity); + }else{ + return true; + } + return false; +} +private validateDates(){ + if(this.projects){ + for (var k = 0; k < this.projects.length; k++) { + var project = this.projects[k]; + console.info(project.startDate+" "+project.endDate + " "+project.projectAcronym); + if(this.results){ + for (var i = 0; i < this.results.length; i++) { + var result = this.results[i]; + if(result.date && result.date != null){ + console.info("Date :"+ result.date + " & embargoEndDate :" +result.embargoEndDate ); + if((project.startDate && result.date < project.startDate) || ( project.endDate && result.date > (project.endDate+5)) ){ + this.confirmOpen(); + return false; + } + } + } + } + + + } + } + if(this.results){ + for (var i = 0; i < this.results.length; i++) { + var result = this.results[i]; + if(result.date && result.date != null){ + console.info("Date :"+ result.date + " & embargoEndDate :" +result.embargoEndDate ); + if((result.embargoEndDate && result.embargoEndDate != null) && result.date >result.embargoEndDate ){ + this.confirmOpen(); + return false; + } + } + } + } + + return true; +} +private afterclaimsInsertion(){ + + this.loading.close(); + this.claiming = false; + + if(this.errorInClaims.length == 0 && this.insertedClaims.length > 0 && this.errorInRecords.length == 0){ + + this._router.navigate( ['/myclaims'] ); + this.showChange.emit({ + value: this.show + }); + }else{ + this.errorsInClaimsInsertion(); + } +} +private errorsInClaimsInsertion(){ + this.errorMessage = ""; + this.loading.close(); + this.error = true; + this.claiming = false; + this.showButton = false; + var text ="" + console.log("Errors: this.errorInRecords.length: "+this.errorInRecords.length+" - this.errorInClaims.length: "+this.errorInClaims.length); + if(this.errorInRecords.length>0){ + text+="
The following records couldn't automatically inserted to the Openaire Info space:
    "; + for(var i=0; i< this.errorInRecords.length ; i++){ + for(var k=0; k< this.results.length ; k++){ + if(this.results[k].id == this.errorInRecords[i]){ + text+="
  • "+this.results[i].title+" from "+this.results[i].source+"
  • "; + } + } + } + text+="
"; + + } + if(this.errorInClaims.length > 0){ + text+="
The following links couldn't be saved:
    "; + for(var i=0; i< this.errorInClaims.length ; i++){ + // var claim = { claimedBy : user, sourceId : context.concept.id, sourceType : "context", sourceCollectedFrom:"openaire", sourceAccessRights:"OPEN", sourceEmbargoEndDate:"no", targetId : result.id , targetType : result.type, targetCollectedFrom: result.source, targetAccessRights:result.accessRights, targetEmbargoEndDate: (result.embargoEndDate == null?"":result.embargoEndDate)}; + + text+="
  • "+this.errorInClaims[i].sourceType+": "+this.errorInClaims[i].sourceId +"(from "+this.errorInClaims[i].sourceCollectedFrom+") link to "+this.errorInClaims[i].targetType+": "+this.errorInClaims[i].targetId +"(from "+this.errorInClaims[i].targetCollectedFrom+")
  • "; + + } + text+="
"; + } + this.errorMessage+="
An error occured:
"+text; + console.log(text); + // if(this.inline){ + // this.show = "error"; + // this.showChange.emit({ + // value: this.show + // }); + // } + +} + + + + private createContextClaim(result:any, context:any, user:any){ + var claim = { claimedBy : user, sourceId : context.concept.id, sourceType : "context", sourceCollectedFrom:"openaire", sourceAccessRights:"OPEN", sourceEmbargoEndDate:"no", targetId : result.id , targetType : result.type, targetCollectedFrom: result.source, targetAccessRights:result.accessRights, targetEmbargoEndDate: (result.embargoEndDate == null?"":result.embargoEndDate)}; + return claim; + } + private createProjectClaim(result:any, project:any, user:any){ + //project.projectId + // var dummyID = "dummyID"; + var claim = { claimedBy : user, sourceId : project.projectId, sourceType : "project", sourceCollectedFrom:"openaire", sourceAccessRights:"OPEN", sourceEmbargoEndDate:"", targetId : result.id , targetType : result.type, targetCollectedFrom: result.source, targetAccessRights:result.accessRights, targetEmbargoEndDate: (result.embargoEndDate == null?"":result.embargoEndDate)}; + return claim; + } + private createResultClaim(inlineResult:any, result:any, user:any){ + var claim = { claimedBy : user, sourceId : result.id, sourceType : result.type, sourceCollectedFrom: result.source, sourceAccessRights: result.accessRights, sourceEmbargoEndDate: result.embargoEndDate, targetId : inlineResult.id , targetType : inlineResult.type, targetCollectedFrom: inlineResult.source, targetAccessRights: inlineResult.accessRights, targetEmbargoEndDate: (inlineResult.embargoEndDate == null?"":inlineResult.embargoEndDate)}; + return claim; + } +createDirectClaim(result, projects, contexts){ + var entity = {}; + var md5_id = Md5.hashStr(result.id); + entity["originalId"]="userclaim___::"+md5_id; + entity["openaireId"]="userclaim___::"+md5_id; + entity["title"]=result.title; + entity["title"] =(Array.isArray(result.title) && result.title.length > 0 )?result.title[0]:result.title; + + if(result.authors && result.authors.length > 0){ + entity["authors"]=result.authors; + } + if(result.publisher){ + entity["publisher"]=result.publisher; + } + if(result.description){ + entity["description"]=result.description; + } + // entity["language"]=""; no info + entity["type"]=result.type; + if(result.source == "crossref" || result.source == "datacite"){ + entity["pids"]= [];//{type:string, value:string}[]; + entity["pids"].push({type:"doi",value:result.id}) + } + entity["licenseCode"]=result.accessRights; + if(result.accessRights == "EMBARGO"){ + entity["embargoEndDate"]=result.embargoEndDate; + } + if(result.type =="publication"){ + entity["resourceType"]="0001"; + }else if(result.type =="dataset"){ + entity["resourceType"]="0021"; + }else if(result.type =="software"){ + entity["resourceType"]="0029"; + } + entity["url"]=result.url; + entity["hostedById"]="openaire____::1256f046-bf1f-4afc-8b47-d0b147148b18"; + if(result.source == "crossref"){ + entity["collectedFromId"]="openaire____::crossref"; + }else if(result.source == "datacite"){ + entity["collectedFromId"]="openaire____::datacite"; + }else if(result.source == "orcid"){ + entity["collectedFromId"]="openaire____::orcid"; + }else if(result.source == "orpenaire"){ + entity["collectedFromId"]="openaire____::driver"; + } + + if(projects.length>0){ + entity["linksToProjects"]=[]; + for(var i =0; i < projects.length; i++){ + // "info:eu-repo/grantAgreement/EC/FP7/283595/EU//OpenAIREplus", + entity["linksToProjects"].push("info:eu-repo/grantAgreement/"+projects[i].funderName+"/"+projects[i].fundingLevel0+"/"+projects[i].code+"/"+projects[i].jurisdiction+"/"+projects[i].projectName+"/"+projects[i].projectAcronym); + } + } + if(contexts.length > 0){ + entity["contexts"]=[]; + for(var i =0; i < contexts.length; i++){ + entity["contexts"].push(contexts[i].concept.id); + } + } + var json = JSON.stringify(entity); + console.log("\nJSON:\n"+json); + return entity; + + + +} + confirmOpen(){ + this.alert.cancelButton = true; + this.alert.okButton = true; + this.alert.alertTitle = "Invalid dates"; + this.alert.message = "There is a research result whose publication date is after project end date or before project start date. Or embargo end date of a research result is before research result's publication date."; + this.alert.okButtonText = "Proceed anyway"; + this.alert.cancelButtonText = "Cancel"; + this.alert.open(); + } + confirmClose(data){ + this.insertActions(); + } +} diff --git a/claims/linking/insertClaim/insertClaim.module.ts b/claims/linking/insertClaim/insertClaim.module.ts new file mode 100644 index 00000000..6b2c4bb0 --- /dev/null +++ b/claims/linking/insertClaim/insertClaim.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../../shared/shared.module'; +import {AlertModalModule} from '../../../utils/modal/alertModal.module'; +import {LoadingModalModule} from '../../../utils/modal/loadingModal.module'; +import {ClaimInsertComponent} from './insertClaim.component'; +import {ClaimServiceModule} from '../../claim-utils/service/claimsService.module'; + +@NgModule({ + imports: [ + SharedModule, AlertModalModule, LoadingModalModule, ClaimServiceModule + ], + declarations: [ClaimInsertComponent], + exports:[ ClaimInsertComponent] +}) +export class InsertClaimsModule { } diff --git a/claims/linking/linking-routing.module.ts b/claims/linking/linking-routing.module.ts new file mode 100644 index 00000000..2660b77f --- /dev/null +++ b/claims/linking/linking-routing.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { LoginGuard} from'../../login/loginGuard.guard'; + +import { LinkingGenericComponent } from './linkingGeneric.component'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: LinkingGenericComponent, canActivate: [IsRouteEnabled, LoginGuard], data: { + redirect: '/error' + }, canDeactivate: [PreviousRouteRecorder]}, + + ]) + ] +}) +export class LinkingRoutingModule { } diff --git a/claims/linking/linking.component.ts b/claims/linking/linking.component.ts new file mode 100644 index 00000000..dbf7a23f --- /dev/null +++ b/claims/linking/linking.component.ts @@ -0,0 +1,16 @@ +// import {Component, Input} from '@angular/core'; +// import {Observable} from 'rxjs/Observable'; +// import {LinkingGenericComponent} from './linkingGeneric.component'; +// +// @Component({ +// selector: 'linking', +// template: ` +// +// ` +// +// }) +// export class LinkingComponent { +// constructor () { +// } +// +// } diff --git a/claims/linking/linkingGeneric.component.html b/claims/linking/linkingGeneric.component.html new file mode 100644 index 00000000..64cbe741 --- /dev/null +++ b/claims/linking/linkingGeneric.component.html @@ -0,0 +1,118 @@ +
+
+
+ +
+
+ Link +
+ +
+ +
+
+ +
+ + + +
    +
  • +

    + + + {{(projects.length + contexts.length + results.length)}} +

    +
    + + + + + +
    +
  • +
+ +
+ + +
    +
  • + + +
  • +
  • + + +
  • + +
+
+ + + + + +
+
+
+ + + + + + + + + + + + +
+ + +
+
+
+ + +
+ + + + +
+ +
+ + + + +
+ +
+
+
diff --git a/claims/linking/linkingGeneric.component.ts b/claims/linking/linkingGeneric.component.ts new file mode 100644 index 00000000..379b8677 --- /dev/null +++ b/claims/linking/linkingGeneric.component.ts @@ -0,0 +1,117 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; +import {EntitiesSearchService} from '../../utils/entitiesAutoComplete/entitySearch.service'; +import {ClaimProject, ClaimResult} from '../claim-utils/claimEntities.class'; +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import {SearchDatasetsService} from '../../services/searchDatasets.service'; +import { Meta} from '../../../angular2-meta'; +declare var UIkit:any; + +@Component({ + selector: 'linking-generic', + templateUrl: 'linkingGeneric.component.html' + +}) +export class LinkingGenericComponent { + + @Input() bulkMode: boolean = false; + sourceType:string; + targetType:string; + step:number = 1; + contexts=[]; + projects=[]; + results = []; + show = "project"; + date='8-6-2016'; + keyword: string = ""; + linkType:string ="project"; // link type (selected in home page) : project, context, software, etc + /* url Parameters for inline linking */ + id:string = null; //entity id + type:string = null; // entity type (publication or research data) + linkTo:string = null; // entity type (project or context or result) + + entityTypes=["dataset", "publication", "project","context"]; + inlineResult:ClaimResult =null; + sub:any =null; + constructor ( private _router: Router, private route: ActivatedRoute, private entitySearch:EntitiesSearchService, + private publicationsSearch:SearchPublicationsService, private datasetsSearch:SearchDatasetsService, private _meta: Meta) { + this._meta.setTitle("OpenAIRE | Linking"); + } + ngOnInit() { + if( typeof localStorage !== 'undefined') { + if(localStorage.getItem("projects")){ + this.projects = JSON.parse(localStorage.getItem("projects")); + + } + if(localStorage.getItem("contexts")){ + this.contexts = JSON.parse(localStorage.getItem("contexts")); + } + if(localStorage.getItem("results")){ + this.results = JSON.parse(localStorage.getItem("results")); + + } + localStorage.removeItem("projects"); + localStorage.removeItem("contexts"); + localStorage.removeItem("results"); + } + } + + next(){ + + if((this.show == 'result' && this.keyword == '')||(this.show == 'dataset' || this.show == 'publication')){ + this.show='claim'; + + } + } + prev(){ + if(this.show == 'claim'){ + this.show='result'; + } + } + + + resultsChange($event) { + this.results=$event.value; + } + + projectsChange($event) { + this.projects=$event.value; + } + + linkTypeChange($event) { + + this.linkType =$event.value; + this.show="result"; + if(this.bulkMode){ + this.show="claim"; + } + } + + showChange($event) { + this.show=$event.value; + this.showChangedType($event.value); + } + + showChangedType(type:string) { + this.show=type; + if(this.show == 'project' || this.show == 'context' || this.show == 'software'){ + this.linkType = this.show; + } + } + + canProceedToMetadata(){ + if(this.results.length == 0){ + + UIkit.notification({ + message : 'No research results selected!
Please select research results to link with projects and/ or ommunities.', + status : 'warning', + timeout : 1000, + pos : 'top-center' + }); + }else{ + this.show = 'claim'; + this.step = 3; + } + } +} diff --git a/claims/linking/linkingGeneric.module.ts b/claims/linking/linkingGeneric.module.ts new file mode 100644 index 00000000..d9627a23 --- /dev/null +++ b/claims/linking/linkingGeneric.module.ts @@ -0,0 +1,37 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import {SelectedProjectsModule} from './selected/selectedProjects.module'; +import {SelectedContextsModule} from './selected/selectedContexts.module'; +import {SelectedPublicationsModule} from './selected/selectedResults.module'; +import {InsertClaimsModule} from './insertClaim/insertClaim.module'; +import {LinkingGenericComponent} from './linkingGeneric.component'; +import {EntitySearchServiceModule} from '../../utils/entitiesAutoComplete/entitySearchService.module'; +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import { LinkingRoutingModule } from './linking-routing.module'; +import {StartOverModule} from '../claim-utils/startOver.module'; +import {LoginGuard} from'../../login/loginGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {ClaimContextSearchFormModule} from '../claim-utils/claimContextSearchForm.module'; +import {ClaimProjectsSearchFormModule} from '../claim-utils/claimProjectSearchForm.module'; +import {BulkClaimModule} from './bulkClaim/bulkClaim.module'; +import {ClaimResultSearchFormModule} from '../claim-utils/claimResultSearchForm.module'; +import {HelperModule} from '../../utils/helper/helper.module'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + SharedModule, SelectedProjectsModule, SelectedContextsModule, + SelectedPublicationsModule, + InsertClaimsModule, + EntitySearchServiceModule, PublicationsServiceModule, DatasetsServiceModule, LinkingRoutingModule, StartOverModule, + ClaimContextSearchFormModule, ClaimProjectsSearchFormModule, BulkClaimModule, ClaimResultSearchFormModule, HelperModule + ], + providers:[LoginGuard, PreviousRouteRecorder, IsRouteEnabled], + declarations: [ + LinkingGenericComponent + ], exports:[ + LinkingGenericComponent ] +}) +export class LinkingGenericModule { } diff --git a/claims/linking/selected/selectedContexts.component.ts b/claims/linking/selected/selectedContexts.component.ts new file mode 100644 index 00000000..c8e572a9 --- /dev/null +++ b/claims/linking/selected/selectedContexts.component.ts @@ -0,0 +1,91 @@ +import {Component, Input,Output, EventEmitter} from '@angular/core'; +import {ClaimContext} from '../../claim-utils/claimEntities.class'; + +@Component({ + selector: 'claim-selected-contexts', + template: ` + + + +
+ + +
+
Selected Communities ({{contexts.length}})
+ +
    +
  • + {{context.community }} > {{context.category}} > {{context.concept.label}} + + +
  • +
+
+
There are no selected communities
+
+ + + + ` +}) +export class ClaimSelectedContextsComponent { + ngOnInit() { + var myDate = new Date(); + this.todayDate=( myDate.getFullYear()+ "-" +myDate.getMonth() + 1) + "-" + myDate.getDate() ; + this.nextDate= ( (myDate.getFullYear()+100)+ "-" +myDate.getMonth() + 1) + "-" + myDate.getDate() ; + //2015-05-01 + // if(this.linkType == "context"){ + this.showsearch = true + // }else{ + // this.showsearch = false; + // } +} + + + @Input() contexts:ClaimContext[]; + //The following need to be kept in case we have to save the current state + @Input() public projects; + @Input() public results; + @Input() public inlineEntity; + @Input() componentClass:string = ""; //"" or "col-sm-6" for horizontal display (besides projects) + @Input() show='home'; + @Input() title='Communities'; + @Input() linkType:string = "project"; + + @Input() hideType; + @Input() bulkMode:boolean = false; + @Output() showChange = new EventEmitter(); + + showsearch:boolean = false; + + todayDate = ''; + nextDate = ''; + + showType(type){ + if(type != this.show){ + this.show = type; + this.showChange.emit({ + value: this.show + }); + } + } + + + removeContext(item:any){ + var index:number =this.contexts.indexOf(item); + if (index > -1) { + this.contexts.splice(index, 1); + } + + } + contextSelected($event) { + // this.showsearch = false; + } + +} diff --git a/claims/linking/selected/selectedContexts.module.ts b/claims/linking/selected/selectedContexts.module.ts new file mode 100644 index 00000000..08d3d059 --- /dev/null +++ b/claims/linking/selected/selectedContexts.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../../shared/shared.module'; +import {ClaimSelectedContextsComponent} from './selectedContexts.component'; +// import {ClaimContextSearchFormModule} from '../../claim-utils/claimContextSearchForm.module'; + + @NgModule({ + imports: [ + SharedModule, + // ClaimContextSearchFormModule + ], + declarations: [ + ClaimSelectedContextsComponent + ], exports:[ClaimSelectedContextsComponent] +}) +export class SelectedContextsModule { } diff --git a/claims/linking/selected/selectedProjects.component.ts b/claims/linking/selected/selectedProjects.component.ts new file mode 100644 index 00000000..d8929ec3 --- /dev/null +++ b/claims/linking/selected/selectedProjects.component.ts @@ -0,0 +1,88 @@ +import {Component, Input,Output, EventEmitter} from '@angular/core'; +import {ClaimProject} from '../../claim-utils/claimEntities.class'; +import {RouterHelper} from '../../../utils/routerHelper.class'; + +@Component({ + selector: 'claim-selected-projects', + template: ` + + +
+ + + +
There are no selected projects
+
+ + + + ` +}) +export class ClaimSelectedProjectsComponent { + + +ngOnInit() { + var myDate = new Date(); + this.todayDate=( myDate.getFullYear()+ "-" +myDate.getMonth() + 1) + "-" + myDate.getDate() ; + this.nextDate= ( (myDate.getFullYear()+100)+ "-" +myDate.getMonth() + 1) + "-" + myDate.getDate() ; + // if(this.linkType == "project"){ + this.showsearch = true + // }else{ + // this.showsearch = false; + // } + //2015-05-01 +} + + +@Input() projects: ClaimProject[]; +@Input() show='home'; +@Input() title='Projects'; +@Input() linkType:string = "project"; +@Input() hideType; +@Input() bulkMode:boolean = false; +@Input() linkToResults:boolean = true; +@Output() projectsChange = new EventEmitter(); +@Output() showChange = new EventEmitter(); +showsearch:boolean = false; + +todayDate = ''; +nextDate = ''; +public routerHelper:RouterHelper = new RouterHelper(); + +removeProject(item:any){ + var index:number =this.projects.indexOf(item); + if (index > -1) { + this.projects.splice(index, 1); + } + this.projectsChange.emit({ + value: this.projects + }); +} +showType(type){ +if(type != this.show){ + this.show = type; + this.showChange.emit({ + value: this.show + }); +} +} +projectSelected($event) { + // this.showsearch = false; +} + + +} diff --git a/claims/linking/selected/selectedProjects.module.ts b/claims/linking/selected/selectedProjects.module.ts new file mode 100644 index 00000000..e3d96ef7 --- /dev/null +++ b/claims/linking/selected/selectedProjects.module.ts @@ -0,0 +1,18 @@ + +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { SharedModule } from '../../../shared/shared.module'; +import {ClaimSelectedProjectsComponent} from './selectedProjects.component'; +// import {ClaimProjectsSearchFormModule} from '../../claim-utils/claimProjectSearchForm.module'; + + @NgModule({ + imports: [ + SharedModule, RouterModule, + // ClaimProjectsSearchFormModule + ], + declarations: [ + ClaimSelectedProjectsComponent + ], exports:[ClaimSelectedProjectsComponent] +}) +export class SelectedProjectsModule { } diff --git a/claims/linking/selected/selectedResults.component.ts b/claims/linking/selected/selectedResults.component.ts new file mode 100644 index 00000000..b1b91aca --- /dev/null +++ b/claims/linking/selected/selectedResults.component.ts @@ -0,0 +1,225 @@ +import {Component, Input,Output, EventEmitter, ViewChild} from '@angular/core'; +import {AlertModal} from '../../../utils/modal/alert'; +import {ClaimResult} from '../../claim-utils/claimEntities.class'; +import {IMyOptions, IMyDateModel} from '../../../utils/my-date-picker/interfaces/index'; +import {Dates} from '../../../utils/string-utils.class'; + +@Component({ + selector: 'claim-selected-results', + template: ` + + + + + +
+
There are no selected research results
+
+
{{title}} ({{results.length}})
+ + + + + + + + + + + + + + + + + + +
Research Result Change type and access mode
+
+ + {{pub.title}} + {{pub.title}} + +
+ + Publisher: {{pub.publisher}} + Journal: {{pub.result['journal-title'].value}} + ({{pub.date.substring(0,4)}}) + +
Authors: {{author}}{{(i < (pub.authors.slice(0,10).length-1))?"; ":""}}{{(i == pub.authors.slice(0,10).length-1 && pub.authors.length > 10)?"...":""}}
+ + + +
Editors: {{author.family}} {{author.given}}{{(i < (pub.result.editor.slice(0,10).length-1))?"; ":""}}{{(i == pub.result.editor.slice(0,10).length-1 && pub.result.editor.length > 10)?"...":""}}
+ + +
Authors: {{author}}{{(i < (pub.result.authors.slice(0,10).length-1))?"; ":""}}{{(i == pub.result.authors.slice(0,10).length-1 && pub.result.authors.length > 10)?"...":""}}
+ + + + + + +
{{pub.source}} + {{pub.accessRights}} + {{pub.type}} +
+
+ + + + + + + + Currently you cannot change metadata from OpenAIRE + +
+
+ + +
+
+
+ + + ` + +}) +export class ClaimSelectedResultsComponent { + ngOnInit() { + var myDate = new Date(); + this.nextDate = { date: { year: myDate.getFullYear()+10, month: (myDate.getMonth()+1), day: myDate.getDate() } }; + //2015-05-01 + +} + + @Input() results: ClaimResult[]; + @Input() title:string = "Research Results"; + @Input() showAccessRights:boolean = false; + @Input() bulkMode:boolean = false; + // @Output()resultsChange = new EventEmitter(); + @Input() showSearch:boolean = false; + nextDate = {}; + @ViewChild(AlertModal) alertApplyAll; + +public commonAccessRights = "OPEN"; // for access rights- changes when user apply a change to every result +public commonEmbargoEndDate; // for access rights: embargoEndDate - changes when user apply a change to every result +public commonType; // for research result type - changes when user apply a change to every result +public typeChanged:boolean = true; // +accessTypes = ["OPEN","CLOSED","EMBARGO","RESTRICTED"]; +private myDatePickerOptions: IMyOptions = { + // other options... + dateFormat: 'yyyy-mm-dd', + selectionTxtFontSize: '15px', + height:'28px', + width: '100%', + editableDateField: false, + showClearDateBtn: false + }; + + + removePublication(item:any){ + var index:number =this.results.indexOf(item); + if (index > -1) { + this.results.splice(index, 1); + } + // this.resultsChange.emit({ + // value: this.results + // }); + } + + + onDateChanged (event:any, item:any) { + item.embargoEndDate = Dates.getDateFromString(event.formatted); + if(this.results.length > 1 ){ + this.commonAccessRights = "EMBARGO"; + this.commonEmbargoEndDate = item.embargoEndDate; + this.confirmOpen(false,"Do you wish to apply the change to every result?"); + } + + } + onTypeChanged (event:any, item:any) { + item.type =(event); + if(this.results.length > 1 ){ + this.commonType = item.type; + this.confirmOpen(true, "Do you wish to apply the change to every result?"); + } + + } + // resultsChanged($event) { + // this.results=$event.value; + // this.resultsChange.emit({ + // value: this.results + // }); + // } + /* The following methods: + *typeChanged + *confirmOpen + *confirmClose + implement the functionality: change accessRights of a publication - apply to all if asked */ + accessRightsTypeChanged (type:any, item:any) { + item.accessRights = type; + if(this.results.length > 1 ){ + this.commonAccessRights = type; + if(this.commonAccessRights != "EMBARGO"){ + this.commonEmbargoEndDate = item.embargoEndDate; + this.confirmOpen(false, "Do you wish to apply the change to every result?"); + } + } + + } + confirmOpen(type: boolean, message: string){ + this.typeChanged = type; + this.alertApplyAll.cancelButton = true; + this.alertApplyAll.okButton = true; + this.alertApplyAll.alertTitle = "Change metadata"; + this.alertApplyAll.message = "Do you wish to apply the change to every result?"; + this.alertApplyAll.okButtonText = "Yes"; + this.alertApplyAll.cancelButtonText = "No"; + this.alertApplyAll.open(); + } + confirmClose(data){ + if(this.typeChanged){ + + for (var i = 0; i < this.results.length; i++) { + if(this.results[i].source != 'openaire' ){ + this.results[i].type = this.commonType; + } + } + + }else{ + for (var i = 0; i < this.results.length; i++) { + if(this.results[i].source != 'openaire' ){ + this.results[i].accessRights = this.commonAccessRights; + if(this.commonAccessRights == "EMBARGO"){ + this.results[i].embargoEndDate = this.commonEmbargoEndDate; + } + } + } + } + } +} diff --git a/claims/linking/selected/selectedResults.module.ts b/claims/linking/selected/selectedResults.module.ts new file mode 100644 index 00000000..0b12fb2d --- /dev/null +++ b/claims/linking/selected/selectedResults.module.ts @@ -0,0 +1,21 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../../shared/shared.module'; +import {ClaimSelectedResultsComponent} from './selectedResults.component'; +import {AlertModalModule} from '../../../utils/modal/alertModal.module'; +import { MyDatePickerModule } from '../../../utils/my-date-picker/my-date-picker.module'; +// import {BulkClaimModule} from '../bulkClaim/bulkClaim.module'; +// import {ClaimResultSearchFormModule} from '../../claim-utils/claimResultSearchForm.module'; + +@NgModule({ + imports: [ + SharedModule, + AlertModalModule, + MyDatePickerModule, + // BulkClaimModule, ClaimResultSearchFormModule, + ], + declarations: [ + ClaimSelectedResultsComponent + ], exports:[ClaimSelectedResultsComponent] +}) +export class SelectedPublicationsModule { } diff --git a/claims/myClaims/myClaims-routing.module.ts b/claims/myClaims/myClaims-routing.module.ts new file mode 100644 index 00000000..a5f99f5f --- /dev/null +++ b/claims/myClaims/myClaims-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { LoginGuard} from'../../login/loginGuard.guard'; + +import { MyClaimsComponent } from './myClaims.component'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: MyClaimsComponent, canActivate: [IsRouteEnabled, LoginGuard], + data: {redirect: '/error'}, canDeactivate: [PreviousRouteRecorder]}]) + ] +}) +export class MyClaimsRoutingModule { } diff --git a/claims/myClaims/myClaims.component.ts b/claims/myClaims/myClaims.component.ts new file mode 100644 index 00000000..7d740def --- /dev/null +++ b/claims/myClaims/myClaims.component.ts @@ -0,0 +1,36 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Meta} from '../../../angular2-meta'; + + +@Component({ + selector: 'my-claims', + template: ` +
+
+
+ +
+
+ My Claims +
+ +
+
+
+
+` + +}) + export class MyClaimsComponent { + constructor ( private _meta: Meta ) { + this._meta.setTitle("OpenAIRE | My Claims"); + } + ngOnInit() { + + } + +} diff --git a/claims/myClaims/myClaims.module.ts b/claims/myClaims/myClaims.module.ts new file mode 100644 index 00000000..e7f0199b --- /dev/null +++ b/claims/myClaims/myClaims.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../../shared/shared.module'; +import { MyClaimsComponent } from './myClaims.component'; +import { MyClaimsRoutingModule } from './myClaims-routing.module'; +// import{ClaimServiceModule} from '../claim-utils/service/claimsService.module'; +import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.module'; +import {LoginGuard} from'../../login/loginGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + SharedModule, + MyClaimsRoutingModule, + // ClaimServiceModule, + DisplayClaimsModule + + ], + providers:[LoginGuard, PreviousRouteRecorder, IsRouteEnabled], + declarations: [ + MyClaimsComponent + ] +}) +export class MyClaimsModule { } diff --git a/claims/myClaimsDemo.component.ts b/claims/myClaimsDemo.component.ts new file mode 100644 index 00000000..6490a59c --- /dev/null +++ b/claims/myClaimsDemo.component.ts @@ -0,0 +1,51 @@ +// import {Component, Input} from '@angular/core'; +// import {Observable} from 'rxjs/Observable'; +// import { Router } from '@angular/router'; +// +// +// +// @Component({ +// selector: 'my-claims-demo', +// template: ` +//
+// +//
+// +// +// +//

Extra parameters for claims admin

+// +// +// +// +// +// +// +//
+//
+// +// +// +// ` +// //(click)="changeOrderby('target')" +// //od_______908::3a5b2885656a91307156325644e73b92 +// +// }) +// export class MyClaimsDemoComponent { +// constructor ( private _router: Router ) { +// } +// user:string="argirok@di.uoa.gr"; +// ngOnInit() { +// +// } +// goToPub(id: number){ +// this._router.navigate( ['Publication', { articleId: id}] ); +// } +// } diff --git a/deposit/datasets/depositBySubject.component.ts b/deposit/datasets/depositBySubject.component.ts new file mode 100644 index 00000000..17a17268 --- /dev/null +++ b/deposit/datasets/depositBySubject.component.ts @@ -0,0 +1,34 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router } from '@angular/router'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + + + +@Component({ + selector: 'deposit-by-subject', + template: ` +
+ +

Or search for domain specific repositories

+ +
+ + + +
+
+ ` +}) + +export class DepositBySubjectComponent { + @Input() subjectKeyword: string=''; + + constructor (private _router: Router) { } + + public search() { + this._router.navigate( ['participate/deposit-subject-result'], { queryParams: { "q": this.subjectKeyword } } ); + } +} diff --git a/deposit/datasets/depositBySubjectResult.component.html b/deposit/datasets/depositBySubjectResult.component.html new file mode 100644 index 00000000..69825626 --- /dev/null +++ b/deposit/datasets/depositBySubjectResult.component.html @@ -0,0 +1,79 @@ + +
+
+
+ +
+
+ Deposit {{requestFor}} +
+ +
+
+ + + +
+
+ Keywords: {{subject}} + +
+
+
+ +
+
+ +
+ + + + +
+

Please use the information/contacts shown below to deposit your {{requestFor}}.

+ +
+ +
+
+ {{fetchDataproviders.searchUtils.totalResults}} content providers, page {{fetchDataproviders.searchUtils.page}} of {{(totalPages())}} +
+ + + +
+ +
+ No content providers found with classification "{{subject}}". +
+
+ An error occured. +
+ +
+ + You can still deposit your {{requestFor}} in + OpenAIRE's Zenodo catch-all repository () + hosted by CERN. +
+
+ +
+ + + +
+
+
+
diff --git a/deposit/datasets/depositBySubjectResult.component.ts b/deposit/datasets/depositBySubjectResult.component.ts new file mode 100644 index 00000000..438db3c1 --- /dev/null +++ b/deposit/datasets/depositBySubjectResult.component.ts @@ -0,0 +1,127 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import { Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; +import { FetchDataproviders } from '../../utils/fetchEntitiesClasses/fetchDataproviders.class'; +import { SearchDataprovidersService } from '../../services/searchDataproviders.service'; + +import {OrganizationService} from '../../services/organization.service'; +import { Meta} from '../../../angular2-meta'; + +import {RouterHelper} from '../../utils/routerHelper.class'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'deposit-by-subject-result', + templateUrl: 'depositBySubjectResult.component.html' +}) + +export class DepositBySubjectResultComponent { + @Input() compatibility: string = ''; + + // Type of entity: Publication or Research Data + @Input() requestFor: string = "Research Data"; + @Input() subject: string = ""; + + public newSubject: string= ""; + + public fetchDataproviders : FetchDataproviders; + public linkToSearchDataproviders = ""; + + // url of Zenodo + public zenodo: string; + + public page: number = 1; + + public status: number; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + sub: any; + piwiksub: any; + + constructor ( private _router: Router, + private route: ActivatedRoute, + private _searchDataprovidersService: SearchDataprovidersService, + private _meta: Meta, private _piwikService:PiwikService) { + + this.zenodo = OpenaireProperties.getZenodoURL(); + this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService); + + this.status = this.errorCodes.LOADING; + this.updateTitle("Deposit "+this.requestFor); + this.updateDescription("Openaire, repositories, open access, content provider, compatibility, organization, deposit "+ this.requestFor); + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView("Deposit "+this.requestFor).subscribe(); + } + } + + + + ngOnInit() { + console.info('depositResult init'); + + this.sub = this.route.queryParams.subscribe(params => { + this.subject = params['q']; + this.newSubject = this.subject; + this.searchDataproviders(); + }); + } + + // ngDoCheck() { + // if(this.organizationId == "" || this.organizationId == undefined) { + // this.organizationId = ""; + // this.status = this.errorCodes.ERROR; + // } + // } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + } + + public totalPages(): number { + let totalPages:any = this.fetchDataproviders.searchUtils.totalResults/(this.fetchDataproviders.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + return totalPages; + } + + public searchDataproviders() { + this.subject = this.newSubject; + this.fetchDataproviders.getResultsBySubjectsForDeposit( (this.subject =="")?"*":this.subject, this.requestFor, this.page, 10); + this.linkToSearchDataproviders = OpenaireProperties.getLinkToSearchDataProviders(); + } + + public goToDeposit() { + if(this.requestFor == "Publications") { + this._router.navigate( ['participate/deposit-publications'] ); + } else if(this.requestFor == "Research Data") { + this._router.navigate( ['participate/deposit-datasets'] ); + } + } + public pageChange($event) { + this.page = +$event.value; + this.searchDataproviders(); + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } +} diff --git a/deposit/datasets/depositBySubjectResults.module.ts b/deposit/datasets/depositBySubjectResults.module.ts new file mode 100644 index 00000000..6445da0c --- /dev/null +++ b/deposit/datasets/depositBySubjectResults.module.ts @@ -0,0 +1,33 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { DepositBySubjectResultComponent } from './depositBySubjectResult.component'; + +import {DepositModule} from '../deposit.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {PagingModule } from '../../utils/paging.module'; +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchResultsModule } from '../../searchPages/searchUtils/searchResults.module'; +import {HelperModule} from '../../utils/helper/helper.module'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DepositModule, + SearchResultsModule, DataProvidersServiceModule, PagingModule, + HelperModule + ], + declarations: [ + + DepositBySubjectResultComponent + + ], + exports: [ + DepositBySubjectResultComponent + ], + providers: [FreeGuard,PreviousRouteRecorder, IsRouteEnabled] +}) +export class DepositBySubjectResultsModule { } diff --git a/deposit/datasets/depositDatasets.component.ts b/deposit/datasets/depositDatasets.component.ts new file mode 100644 index 00000000..4c468aeb --- /dev/null +++ b/deposit/datasets/depositDatasets.component.ts @@ -0,0 +1,21 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'deposit-datasets', + template: ` +
+
+
+ +
+ +
+
+
+
+ ` +}) + +export class DepositDatasetsComponent { + +} diff --git a/deposit/datasets/depositDatasets.module.ts b/deposit/datasets/depositDatasets.module.ts new file mode 100644 index 00000000..471b277a --- /dev/null +++ b/deposit/datasets/depositDatasets.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { DepositDatasetsComponent } from './depositDatasets.component'; +import { DepositDatasetsResultComponent } from './depositDatasetsResult.component'; + import {DepositModule} from '../deposit.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DepositModule + ], + declarations: [ + + DepositDatasetsComponent + + ], + exports: [ + DepositDatasetsComponent + ], + providers: [FreeGuard,PreviousRouteRecorder, IsRouteEnabled] +}) +export class DepositDatasetsModule { } diff --git a/deposit/datasets/depositDatasetsResult.component.ts b/deposit/datasets/depositDatasetsResult.component.ts new file mode 100644 index 00000000..edbe92db --- /dev/null +++ b/deposit/datasets/depositDatasetsResult.component.ts @@ -0,0 +1,14 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'deposit-datasets-result', + template: ` + + + + ` +}) + +export class DepositDatasetsResultComponent { + +} diff --git a/deposit/datasets/depositDatasetsResults.module.ts b/deposit/datasets/depositDatasetsResults.module.ts new file mode 100644 index 00000000..cdad3153 --- /dev/null +++ b/deposit/datasets/depositDatasetsResults.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { DepositDatasetsResultComponent } from './depositDatasetsResult.component'; + +import {DepositModule} from '../deposit.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DepositModule + ], + declarations: [ + + DepositDatasetsResultComponent, + + ], + exports: [ + DepositDatasetsResultComponent, + ], + providers: [FreeGuard,PreviousRouteRecorder, IsRouteEnabled] +}) +export class DepositDatasetsResultsModule { } diff --git a/deposit/deposit.component.html b/deposit/deposit.component.html new file mode 100644 index 00000000..f18817f4 --- /dev/null +++ b/deposit/deposit.component.html @@ -0,0 +1,56 @@ +
+
+ Deposit {{requestFor}} +
+
+ +
+
+ +
+ +

See if your institution has a repository

+ +
+
+ + +
+ + +
+
+ +
+
+

Or locate repository on map

+
+ +
+
+
+ +
+ +
diff --git a/deposit/deposit.component.ts b/deposit/deposit.component.ts new file mode 100644 index 00000000..04565a11 --- /dev/null +++ b/deposit/deposit.component.ts @@ -0,0 +1,91 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router } from '@angular/router'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import { Meta} from '../../angular2-meta'; +import {PiwikService} from '../utils/piwik/piwik.service'; + + +@Component({ + selector: 'deposit', + templateUrl: 'deposit.component.html' +}) + +export class DepositComponent { + @Input() compatibility: string = ''; + @Input() mapUrl: string = null; // optional in case i-frame is needed + @Input() searchBySubjects: boolean = false; // optional: in case search by subjects is needed + + + public status: number; + + // Type of entity: Publication or Research Data + @Input() requestFor: string = "Publications"; + + // url's needed for information text + public openAccess: string; + public openAccessRepo: string; + public fp7Guidlines: string; + public h2020Guidlines: string; + public ercGuidlines: string; + public helpdesk: string; + + // Id of the new selected organization to be searched + public selectedId: string = ""; + + public warningMessage: string = ""; + + piwiksub:any; + + constructor (private _router: Router, private _meta: Meta, private _piwikService:PiwikService) { + + this.openAccess = OpenaireProperties.getOpenAccess(); + this.openAccessRepo = OpenaireProperties.getOpenAccessRepo(); + this.fp7Guidlines = OpenaireProperties.getFP7Guidlines(); + this.h2020Guidlines = OpenaireProperties.getH2020Guidlines(); + this.ercGuidlines = OpenaireProperties.getERCGuidlines(); + this.helpdesk = OpenaireProperties.getHelpdesk(); + this.updateTitle("Deposit "+this.requestFor); + this.updateDescription("Openaire, repositories, open access, content provider, compatibility, organization, deposit "+ this.requestFor); + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView("Deposit "+this.requestFor).subscribe(); + } + } + ngOnDestroy() { + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + } + + public organizationSelected(id: string) { + console.info("organization selected"); + if(id && id.length > 0){ + if(this.requestFor == "Publications") { + this._router.navigate( ['participate/deposit-publications-result'], { queryParams: { "organizationId": id } } ); + } else if(this.requestFor == "Research Data") { + this._router.navigate( ['participate/deposit-datasets-result'], { queryParams: { "organizationId": id } } ); + } + } else { + this.warningMessage = "No organization selected"; + } + } + + public valueChanged($event){ + this.selectedId = $event.value; + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } +} diff --git a/deposit/deposit.module.ts b/deposit/deposit.module.ts new file mode 100644 index 00000000..8eaf0b55 --- /dev/null +++ b/deposit/deposit.module.ts @@ -0,0 +1,45 @@ +/* Common Component of deposit for both research data & ppublications*/ + +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import { DepositComponent } from './deposit.component'; +import { DepositResultComponent } from './depositResult.component'; +import {EntitiesAutocompleteModule} from '../utils/entitiesAutoComplete/entitiesAutoComplete.module'; +import {DataProvidersServiceModule} from '../services/dataProvidersService.module'; +import {OrganizationServiceModule} from '../services/organizationService.module'; +import {SearchResultsModule } from '../searchPages/searchUtils/searchResults.module'; +import {PiwikServiceModule} from '../utils/piwik/piwikService.module'; +import {HelperModule} from '../utils/helper/helper.module'; +import { DepositBySubjectComponent } from './datasets/depositBySubject.component'; +import {IFrameModule} from '../utils/iframe.module'; + + + + @NgModule({ + imports: [ + CommonModule, FormsModule, + RouterModule, + EntitiesAutocompleteModule, + DataProvidersServiceModule, + OrganizationServiceModule, + SearchResultsModule, + PiwikServiceModule, + HelperModule, + IFrameModule + ], + declarations: [ + DepositComponent, + DepositResultComponent, + DepositBySubjectComponent + ], + exports: [ + DepositComponent, + DepositResultComponent + ], + providers: [ + ] +}) +export class DepositModule { } diff --git a/deposit/depositResult.component.ts b/deposit/depositResult.component.ts new file mode 100644 index 00000000..bbd41c31 --- /dev/null +++ b/deposit/depositResult.component.ts @@ -0,0 +1,283 @@ +import {Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties, ErrorCodes} from '../utils/properties/openaireProperties'; +import { Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; +import { FetchDataproviders } from '../utils/fetchEntitiesClasses/fetchDataproviders.class'; +import { SearchDataprovidersService } from '../services/searchDataproviders.service'; + +import {OrganizationService} from '../services/organization.service'; +import { Meta} from '../../angular2-meta'; + +import {RouterHelper} from '../utils/routerHelper.class'; +import {PiwikService} from '../utils/piwik/piwik.service'; + +@Component({ + selector: 'deposit-result', + template: ` +
+
+
+ +
+ + +
+ +
+ + + + + + +
+

+ + {{organization['name']}} + + {{organization['name']}} +

+ + +
+ +
+

Please use the information below and contact your repository to deposit your {{requestFor}}.

+ + + + +
+ + +
+
+ + An error occured. + + No content providers found for institution: + + {{organization['name']}} () + + {{organization['name']}} + . +
+
+ No organization with ID: {{organizationId}} found. +
+
+ An error occured. +
+ + Service temprorarily unavailable. Please try again later. + +
+ No ID for organization. +
+ + You can still deposit your {{requestFor}} in + OpenAIRE's Zenodo catch-all repository () + hosted by CERN. +
+
+ +
+ + +
+
+
+
+ + ` +}) + +export class DepositResultComponent { + @Input() compatibility: string = ''; + + // Type of entity: Publication or Research Data + @Input() requestFor: string = "Publications"; + + public organization: {"name": string, "url": string}; + public organizationId: string = ""; + + // Id of the new selected organization to be searched + public selectedId: string = ""; + + public status: number; + public warningMessage: string = ""; + + public fetchDataproviders : FetchDataproviders; + public linkToSearchDataproviders: string = ""; + + // url of Zenodo + public zenodo: string; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + sub: any; piwiksub: any; + + constructor ( private _router: Router, + private route: ActivatedRoute, + private _searchDataprovidersService: SearchDataprovidersService, + private _organizationService: OrganizationService, + private _meta: Meta, private _piwikService:PiwikService) { + + this.zenodo = OpenaireProperties.getZenodoURL(); + this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService); + + this.status = this.errorCodes.LOADING; + this.updateTitle("Deposit "+this.requestFor); + this.updateDescription("Openaire, repositories, open access, content provider, compatibility, organization, deposit "+ this.requestFor); + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView("Deposit "+this.requestFor).subscribe(); + } + } + + ngOnInit() { + console.info('depositResult init'); + + this.sub = this.route.queryParams.subscribe(params => { + this.organizationId = params['organizationId']; + console.info("Id is :"+this.organizationId); + if(this.organizationId){ + this.getOrganizationInfo(); + } + this.selectedId = ""; + }); + } + + ngDoCheck() { + if(this.organizationId == "" || this.organizationId == undefined) { + this.organizationId = ""; + this.status = this.errorCodes.ERROR; + } + } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + } + + private searchDataproviders() { + // if(this.organization != undefined) { + // this.fetchDataproviders.getResults(this.organization.name, false, 1, 10); + // } else if(this.organizationId != undefined) { + this.fetchDataproviders.getResultsForDeposit( this.organizationId,this.requestFor, 1, 10); + //} + this.linkToSearchDataproviders = OpenaireProperties.getLinkToSearchDataProviders(); + } + + private getOrganizationInfo () { + console.info("inside getOrganizationInfo of component"); + + this._organizationService.getOrganizationInfo(this.organizationId).subscribe( + data => { + if(data == null) { + this.status = this.errorCodes.NOT_FOUND; + } else { + this.organization = data.title; + this.status = this.errorCodes.DONE; + this.searchDataproviders(); + } + }, + err => { + //console.log(err) + + if(err.status == '404') { + this.status = this.errorCodes.NOT_FOUND; + console.info("not found"); + } else if(err.status == '500') { + this.status = this.errorCodes.ERROR; + console.info("error"); + } else { + this.status = this.errorCodes.NOT_AVAILABLE; + console.info("not available"); + } + } + ); + } + + public goToDeposit() { + if(this.requestFor == "Publications") { + this._router.navigate( ['participate/deposit-publications'] ); + } else if(this.requestFor == "Research Data") { + this._router.navigate( ['participate/deposit-datasets'] ); + } + } + + public valueChanged($event){ + this.selectedId = $event.value; + } + + public organizationSelected(id: string) { + console.info("organization selected"); + if(id && id.length > 0 && id != this.organizationId){ + this.organization = null; + this.status = this.errorCodes.LOADING; + + if(this.requestFor == "Publications") { + this._router.navigate( ['participate/deposit-publications-result'], { queryParams: { "organizationId": id } } ); + } else if(this.requestFor == "Research Data") { + this._router.navigate( ['participate/deposit-datasets-result'], { queryParams: { "organizationId": id } } ); + } + } else { + this.warningMessage = "No new organization selected"; + } + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } +} diff --git a/deposit/publications/depositPublications.component.ts b/deposit/publications/depositPublications.component.ts new file mode 100644 index 00000000..77ff9a23 --- /dev/null +++ b/deposit/publications/depositPublications.component.ts @@ -0,0 +1,21 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'deposit-publications', + template: ` +
+
+
+ +
+ +
+
+
+
+ ` +}) + +export class DepositPublicationsComponent { + public mapUrl ="https://beta.openaire.eu/stats/markers-demo.html"; +} diff --git a/deposit/publications/depositPublications.module.ts b/deposit/publications/depositPublications.module.ts new file mode 100644 index 00000000..77e922bf --- /dev/null +++ b/deposit/publications/depositPublications.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { DepositPublicationsComponent } from './depositPublications.component'; + +import {DepositModule} from '../deposit.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DepositModule + ], + declarations: [ + DepositPublicationsComponent + ], + exports: [ + DepositPublicationsComponent, + ], + providers: [FreeGuard,PreviousRouteRecorder, IsRouteEnabled] +}) +export class DepositPublicationsModule { } diff --git a/deposit/publications/depositPublicationsResult.component.ts b/deposit/publications/depositPublicationsResult.component.ts new file mode 100644 index 00000000..c7da81eb --- /dev/null +++ b/deposit/publications/depositPublicationsResult.component.ts @@ -0,0 +1,12 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'deposit-publications-result', + template: ` + + ` +}) + +export class DepositPublicationsResultComponent { + +} diff --git a/deposit/publications/depositPublicationsResults.module.ts b/deposit/publications/depositPublicationsResults.module.ts new file mode 100644 index 00000000..9a8e144a --- /dev/null +++ b/deposit/publications/depositPublicationsResults.module.ts @@ -0,0 +1,26 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { DepositPublicationsResultComponent } from './depositPublicationsResult.component'; + +import {DepositModule} from '../deposit.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DepositModule + + ], + declarations: [ + DepositPublicationsResultComponent + ], + exports: [ + DepositPublicationsResultComponent + ], + providers: [FreeGuard,PreviousRouteRecorder, IsRouteEnabled] +}) +export class DepositPublicationsResultsModule { } diff --git a/error/error.module.ts b/error/error.module.ts new file mode 100644 index 00000000..7cea4c20 --- /dev/null +++ b/error/error.module.ts @@ -0,0 +1,17 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {ErrorPageComponent } from './errorPage.component'; +import {MetaModule} from '../../meta.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, MetaModule + ], + providers:[], + declarations: [ + ErrorPageComponent +], exports:[ErrorPageComponent] +}) +export class ErrorModule { } diff --git a/error/errorPage.component.ts b/error/errorPage.component.ts new file mode 100644 index 00000000..30029577 --- /dev/null +++ b/error/errorPage.component.ts @@ -0,0 +1,55 @@ +import { Component, Input } from '@angular/core'; +import { Location } from '@angular/common'; +import { Meta} from '../../angular2-meta'; +import {ActivatedRoute} from '@angular/router'; + +@Component({ + selector: 'error', + template: ` +
+
+
+ +
+

+ Bad karma: we can't find that page! +

+
+ +

+ You asked for {{page}}, but despite our computers looking very hard, we could not find it. What happened ? +

+ +
    +
  • the link you clicked to arrive here has a typo in it
  • +
  • or somehow we removed that page, or gave it another name
  • +
  • or, quite unlikely for sure, maybe you typed it yourself and there was a little mistake ?
  • +
+ +
+
+
+
+ ` +}) + +export class ErrorPageComponent { + public page: string; + + constructor (private _location: Location, private _meta: Meta,private route: ActivatedRoute) { + this._meta.setTitle("OpenAIRE | Error page"); + this.page = _location.path(true); + //this.page = _router.url; + //this.page = location.href; + } + ngOnInit() { + this.route.queryParams.subscribe(data => { + + + this.page = data['page']; + if(!this.page){ + this.page = this._location.path(true); + } + }); + } +} diff --git a/error/isRouteEnabled.guard.ts b/error/isRouteEnabled.guard.ts new file mode 100644 index 00000000..f196f322 --- /dev/null +++ b/error/isRouteEnabled.guard.ts @@ -0,0 +1,23 @@ +import { Injectable } from '@angular/core'; +import { Router,CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router'; +import {Observable} from 'rxjs/Observable'; +import 'rxjs/add/operator/filter'; +import { ConfigurationService } from '../utils/configuration/configuration.service'; + +@Injectable() +export class IsRouteEnabled implements CanActivate { + + constructor(private router: Router, private config: ConfigurationService) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | boolean { + let customRedirect = route.data['redirect']; + console.log("In IsRouteEnabled"); + console.log(state.url.split("?")[0].substring(1)); + let isEnabled = this.config.isPageEnabled(state.url.split("?")[0].substring(1)); + let redirect = !!customRedirect ? customRedirect : '/error'; + isEnabled.filter(enabled => !enabled) + .subscribe(() => this.router.navigate([redirect], { queryParams: { "page": state.url } })); + + return isEnabled; + } +} diff --git a/landingPages/dataProvider/dataProvider-routing.module.ts b/landingPages/dataProvider/dataProvider-routing.module.ts new file mode 100644 index 00000000..8fb2f38f --- /dev/null +++ b/landingPages/dataProvider/dataProvider-routing.module.ts @@ -0,0 +1,18 @@ +// import { NgModule } from '@angular/core'; +// import { RouterModule } from '@angular/router'; +// +// import { DataProviderComponent } from './dataProvider.component'; +// import {FreeGuard} from'../../login/freeGuard.guard'; +// import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +// import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; +// +// @NgModule({ +// imports: [ +// RouterModule.forChild([ +// { path: '', component: DataProviderComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { +// redirect: '/error' +// },canDeactivate: [PreviousRouteRecorder] } +// ]) +// ] +// }) +// export class DataProviderRoutingModule { } diff --git a/landingPages/dataProvider/dataProvider.component.html b/landingPages/dataProvider/dataProvider.component.html new file mode 100644 index 00000000..2a5d336a --- /dev/null +++ b/landingPages/dataProvider/dataProvider.component.html @@ -0,0 +1,234 @@ +
+
+
+ +
+ + + + +
+ +
+ + +
{{dataProviderInfo.officialName}}
+ + {{dataProviderInfo.type}} + {{dataProviderInfo.compatibility}} + + + + +
+ + + + + + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+

Latest Research Result Timeline

+ +

Research Result Types

+ +
+ + +
+ +

Funders in Research Results of content provider

+ + +
+
+

Projects with most Publications

+ +
+
+
+

Projects with most Research Data

+ +
+
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
+ Share - Bookmark +
+
+
+
+
+
+
+
diff --git a/landingPages/dataProvider/dataProvider.component.ts b/landingPages/dataProvider/dataProvider.component.ts new file mode 100644 index 00000000..155960ee --- /dev/null +++ b/landingPages/dataProvider/dataProvider.component.ts @@ -0,0 +1,385 @@ +import {Component, ViewChild, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {DataProviderService} from './dataProvider.service'; +import {DataProviderInfo} from '../../utils/entities/dataProviderInfo'; +import {ActivatedRoute, Router} from '@angular/router'; +import { Meta} from '../../../angular2-meta'; +import { FetchPublications } from '../../utils/fetchEntitiesClasses/fetchPublications.class'; +import { SearchPublicationsService } from '../../services/searchPublications.service'; +import { FetchDatasets } from '../../utils/fetchEntitiesClasses/fetchDatasets.class'; +import { SearchDatasetsService } from '../../services/searchDatasets.service'; +import { FetchProjects } from '../../utils/fetchEntitiesClasses/fetchProjects.class'; +import { SearchProjectsService } from '../../services/searchProjects.service'; +import { FetchDataproviders } from '../../utils/fetchEntitiesClasses/fetchDataproviders.class'; +import { SearchDataprovidersService } from '../../services/searchDataproviders.service'; +import { RelatedDatasourcesTabComponent } from './relatedDatasourcesTab.component'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../utils/routerHelper.class'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +import 'rxjs/add/operator/switch'; +import 'rxjs/add/operator/switchMap'; + +@Component({ + selector: 'dataprovider', + templateUrl: 'dataProvider.component.html', + }) + +export class DataProviderComponent { + public dataProviderInfo: DataProviderInfo; + public datasourceId: string; + + // Message variables + public warningMessage = ""; + public errorMessage = ""; + public showLoading: boolean = true; + + // Variable to specify requests with either collectedFrom or hostedBy + public paramsForSearchLink = {}; + + // Metrics tab variables + public metricsClicked: boolean; + public viewsFrameUrl: string; + public downloadsFrameUrl: string; + public totalViews: number; + public totalDownloads: number; + public pageViews: number; + + // Statistics tab variables + public statsClicked: boolean = false; + public docsTimelineUrl: string; + public docsTypesUrl:string; + public docsFunderUrl:string; + public dataProjectsUrl:string ; + public pubsProjectsUrl:string; + + // Variables for publications, research data, projects, content providers, related content providers tabs + public fetchPublications : FetchPublications; + public fetchDatasets: FetchDatasets; + public fetchProjects: FetchProjects; + public fetchDataproviders: FetchDataproviders; + public fetchAggregatorsPublications: FetchPublications; + public fetchAggregatorsDatasets: FetchDatasets; + + public loadingRelatedDatasources: boolean = true; + + // Active tab variable for responsiveness - show tabs only if main request is completed + public activeTab: string = ""; + public showTabs:boolean = false; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + // Request results of each tab only the one time (first time tab is clicked) + private reloadPublications: boolean = true; + private reloadDatasets: boolean = true; + private reloadProjects: boolean = true; + private reloadDataproviders: boolean = true; + private reloadRelatedDatasources: boolean = true; + + private nativeElement : Node; + + sub: any; + piwiksub: any; + subInfo: any; + relatedDatasourcesSub: any; + + constructor (private element: ElementRef, + private _dataproviderService: DataProviderService, + private _piwikService:PiwikService, + private route: ActivatedRoute, + private _meta: Meta, + private _router: Router, + private _searchPublicationsService: SearchPublicationsService, + private _searchDatasetsService: SearchDatasetsService, + private _searchProjectsService: SearchProjectsService, + private _searchDataprovidersService: SearchDataprovidersService) { + this.fetchPublications = new FetchPublications(this._searchPublicationsService); + this.fetchDatasets = new FetchDatasets(this._searchDatasetsService); + this.fetchProjects = new FetchProjects(this._searchProjectsService); + this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService); + + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(data => { + this.updateTitle("Content provider"); + this.updateDescription("Content provider, search, repositories, open access"); + this.datasourceId = data['datasourceId']; + if(this.datasourceId){ + this.getDataProviderInfo(this.datasourceId); + }else{ + // console.info("Content Provider id not found"); + } + + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + }); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.subInfo) { + this.subInfo.unsubscribe(); + } + + if(this.relatedDatasourcesSub) { + this.relatedDatasourcesSub.unsubscribe(); + } + } + private getDataProviderInfo(id:string) { + this.warningMessage = ''; + this.errorMessage="" + this.showLoading = true; + + this.showTabs = false ; + if(this.datasourceId==null || this.datasourceId==''){ + this.showLoading = false; + this.warningMessage="No valid datasource id"; + }else{ + this.subInfo = this._dataproviderService.getDataproviderInfo(this.datasourceId).subscribe( + data => { + this.dataProviderInfo = data; + this.initTabs(); + this.showTabs = true ; + this.updateTitle(this.dataProviderInfo.title.name); + this.updateDescription("Content provider, search, repositories, open access,"+this.dataProviderInfo.title.name); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.dataProviderInfo.title.name).subscribe(); + } + + this.showLoading = false; + + if(this.dataProviderInfo.tabs != undefined && this.dataProviderInfo.tabs.length > 0) { + this.activeTab = this.dataProviderInfo.tabs[0].name; + } + }, + err => { + console.log(err); + // console.info("error"); + this.errorMessage = 'No dataProvider found'; + this.showLoading = false; + } + ); + } + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + private initTabs(){ + + if(this.dataProviderInfo.tabs != undefined && this.dataProviderInfo.tabs.length > 0) { + this.reloadPublications = true; + this.reloadDatasets = true; + this.reloadProjects = true; + this.reloadDataproviders = true; + this.reloadRelatedDatasources = true; + this.statsClicked = false; + + this.search(this.dataProviderInfo.tabs[0].content, 1, 10); + this.count(1, 0); + + this.metricsClicked = false; + + this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"dtsrcRepoViews","dtsrcName":"'+this.datasourceId+'","table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":"","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[]}]&info_types=["column"]&stacking=&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(124, 181, 236, 1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false'; + /*this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"dtsrcOpenAIRETimeline", "dtsrcName":"'+this.datasourceId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":"","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"OpenAIRE","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]},{"query":"dtsrcRepoTimeline", "dtsrcName":"'+this.datasourceId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":" ","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"Repository","yaxisheaders":[""],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column","column"]&stacking=normal&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(124, 181, 236, 1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true'; + */ + + this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"dtsrcRepoDownloads","dtsrcName":"'+this.datasourceId+'","table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":"","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[]}]&info_types=["column"]&stacking=&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(124, 181, 236, 1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false'; + /* + this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"dtsrcDownloadsTimeline","dtsrcName":"'+this.datasourceId+'","table":"","fields":[{"fld":"sum","agg":"sum","type":"chart","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":"","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[]}]&info_types=["spline"]&stacking=&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(124, 181, 236, 1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true'; + */ + + this.docsTimelineUrl ='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcYear","dtsrcName":"'+this.datasourceId+'","table": "result", "fields": [{"fld": "number", "agg": "count", "type": "line", "yaxis":1, "c":true}], "xaxis":{"name": "year", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": -30, "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Results"], "in": [{"f":0, "text": "Yearly"}], "filters": [{"name":"year","max":"2016","min":"1997"},{"name": "result_datasources-datasource-name", "values":[""], "to": "-1"}],"having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": "Year"}&w=600&h=250'; + this.docsTypesUrl = 'https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcPubs","dtsrcName":"'+this.datasourceId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "pie", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Results"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.docsFunderUrl =' https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcPubsFund","dtsrcName":"'+this.datasourceId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "pie", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Results"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.dataProjectsUrl ='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcProjData","dtsrcName":"'+this.datasourceId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "bar", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Data"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.pubsProjectsUrl ='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcProjPubs","dtsrcName":"'+this.datasourceId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "bar", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Publications"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + + //if({"name": "Publications", "content": "publicationsTab"} in this.dataProviderInfo.tabs) { + //if(this.dataProviderInfo.tabs.some(function (tab) { + // return tab.name === 'Publications'; + //})) { + // this.relatedDataprovidersResultsType = 'publications'; + this.fetchAggregatorsPublications = new FetchPublications(this._searchPublicationsService); + //} else { + // this.relatedDataprovidersResultsType = 'datasets'; + this.fetchAggregatorsDatasets = new FetchDatasets(this._searchDatasetsService); + //} + } + if(this.dataProviderInfo.resultsBy == "collectedFrom") { + //this.paramsForSearchLink = "?collectedFrom="+this.datasourceId+"&co=and"; + this.paramsForSearchLink = this.routerHelper.createQueryParams(['collectedFrom', 'co'], [this.datasourceId, 'and']); + } else if (this.dataProviderInfo.resultsBy == "hostedBy") { + //this.paramsForSearchLink = "?hostedBy="+this.datasourceId+"&ho=and"; + this.paramsForSearchLink = this.routerHelper.createQueryParams(['hostedBy', 'ho'], [this.datasourceId, 'and']); + } + + } + + private count(page: number, size: number) { + for(let i=1; i {}, + err => {}, + () => { this.preprocessRelatedDatasources(); } + ) + + this.fetchAggregatorsPublications.getAggregatorResults(this.datasourceId, page, size); + this.fetchAggregatorsDatasets.getAggregatorResults(this.datasourceId, page, size); + } else { + this.loadingRelatedDatasources = false; + } + + + this.reloadRelatedDatasources = false; + } + + private countRelatedDatasources(page: number, size: number) { + this.fetchAggregatorsPublications.getAggregatorResults(this.datasourceId, page, size); + this.fetchAggregatorsDatasets.getAggregatorResults(this.datasourceId, page, size); + } + + + private preprocessRelatedDatasources() { + if( this.fetchAggregatorsPublications.searchUtils.status == this.errorCodes.DONE || + this.fetchAggregatorsDatasets.searchUtils.status == this.errorCodes.DONE ) { + this.dataProviderInfo.relatedDatasources = new Map(); + } + for(let result of this.fetchAggregatorsPublications.results) { + if(!this.dataProviderInfo.relatedDatasources.has(result.id)) { + this.dataProviderInfo.relatedDatasources.set(result.id, {"name": result.name, "countPublications": result.count, "countDatasets": "0"}); + } else { + this.dataProviderInfo.relatedDatasources.get(result.id).countPublications = parseInt(this.dataProviderInfo.relatedDatasources.get(result.id).countPublications + result.count)+""; + } + } + + for(let result of this.fetchAggregatorsDatasets.results) { + if(!this.dataProviderInfo.relatedDatasources.has(result.id)) { + this.dataProviderInfo.relatedDatasources.set(result.id, {"name": result.name, "countPublications": "0", "countDatasets": result.count}); + } else { + this.dataProviderInfo.relatedDatasources.get(result.id).countDatasets = parseInt(this.dataProviderInfo.relatedDatasources.get(result.id).countDatasets + result.count)+""; + } + } + this.loadingRelatedDatasources = false; + } + + public metricsResults($event) { + this.totalViews = $event.totalViews; + this.totalDownloads = $event.totalDownloads; + this.pageViews = $event.pageViews; + } +} diff --git a/landingPages/dataProvider/dataProvider.module.ts b/landingPages/dataProvider/dataProvider.module.ts new file mode 100644 index 00000000..61f42205 --- /dev/null +++ b/landingPages/dataProvider/dataProvider.module.ts @@ -0,0 +1,51 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {IFrameModule} from '../../utils/iframe.module'; +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; +// import { ResultLandingModule } from '../resultLanding.module'; +import {TabResultModule } from '../../searchPages/searchUtils/tabResult.module'; +import {MetricsModule} from '../landing-utils/metrics.module'; +import {LandingModule} from '../landing-utils/landing.module'; +import {PagingModule} from '../../utils/paging.module'; + +import {PublicationsTabComponent} from './publicationsTab.component'; +import {DatasetsTabComponent} from './datasetsTab.component'; +import {StatisticsTabComponent} from './statisticsTab.component'; +import {ProjectsTabComponent} from './projectsTab.component'; +import {DatasourcesTabComponent} from './datasourcesTab.component'; +import {OrganizationsTabComponent} from './organizationsTab.component'; +import {RelatedDatasourcesTabComponent} from './relatedDatasourcesTab.component'; +// import {TabsComponent} from './tabs.component'; + +import {DataProviderComponent} from './dataProvider.component'; +import {DataProviderService} from './dataProvider.service'; +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import {ProjectsServiceModule} from '../../services/projectsService.module'; +import {PublicationsServiceModule} from '../../services/publicationsService.module'; + +// import { DataProviderRoutingModule } from './dataProvider-routing.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: + [CommonModule, FormsModule, RouterModule, + TabResultModule, IFrameModule, ErrorMessagesModule, MetricsModule, LandingModule, + DataProvidersServiceModule, DatasetsServiceModule, ProjectsServiceModule, PublicationsServiceModule, + PagingModule], + declarations: + [PublicationsTabComponent, DatasetsTabComponent, StatisticsTabComponent, ProjectsTabComponent, DatasourcesTabComponent, OrganizationsTabComponent, + RelatedDatasourcesTabComponent, DataProviderComponent + ], + providers:[ + DataProviderService, FreeGuard, IsRouteEnabled], + exports: [ + DataProviderComponent + ] + +}) +export class DataProviderModule { } diff --git a/landingPages/dataProvider/dataProvider.service.ts b/landingPages/dataProvider/dataProvider.service.ts new file mode 100644 index 00000000..4b549e8d --- /dev/null +++ b/landingPages/dataProvider/dataProvider.service.ts @@ -0,0 +1,162 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {DataProviderInfo} from '../../utils/entities/dataProviderInfo'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + + +@Injectable() +export class DataProviderService { + + constructor(private http: Http ) {} + + dataProviderInfo: DataProviderInfo; + + getDataproviderInfo (id: string):any { + console.info("getDataProviderInfo in service"); + let url = OpenaireProperties.getSearchAPIURLLast() + 'datasources/' +id +"?format=json"; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => res['result']['metadata']['oaf:entity']) + .map(res => [res['oaf:datasource'], + res['oaf:datasource']['datasourcetype'], + res['oaf:datasource']['openairecompatibility'], + res['oaf:datasource']['accessinfopackage'], + res['oaf:datasource']['rels']['rel'] + ]) + .map(res => this.parseDataProviderInfo(res)); + + } + + 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.log(error); + return Observable.throw(error || 'Server error'); + } + + parseDataProviderInfo (data: any):any { + this.dataProviderInfo = new DataProviderInfo(); + + if(data[0] != null) { + this.dataProviderInfo.title = {"name": (data[0].englishname)?data[0].englishname: data[0].officialname, "url": data[0].websiteurl}; + this.dataProviderInfo.officialName = data[0].officialname; + var originalId =(data[0].originalId)?data[0].originalId:""; + if(originalId && originalId != ""){ + if(originalId.indexOf("opendoar____::") != -1){ + this.dataProviderInfo.openDoarURL = "http://www.opendoar.org/find.php?format=full&rID="+originalId.split("opendoar____::")[1]; + + }else if (originalId.indexOf("re3data_____::") != -1){ + this.dataProviderInfo.r3DataURL = "http://service.re3data.org/repository/"+originalId.split("re3data_____::")[1]; + } + } + + } + + if(data[1] != null) { + this.dataProviderInfo.type = data[1].classname; + + if(data[1].classid == "entityregistry" || data[1].classid == "entityregistry::projects" || data[1].classid == "entityregistry::repositories") { + this.dataProviderInfo.registry = true; + } else { + this.dataProviderInfo.registry = false; + } + + if(this.dataProviderInfo.tabs == undefined) { + this.dataProviderInfo.tabs = new Array<{"name": string, "content": string}>(); + } + + if(this.dataProviderInfo.tabsInTypes.publicationsTab.has(data[1].classid)) { + this.dataProviderInfo.tabs.push({"name": "Publications", "content": "publicationsTab"}); + } + if(this.dataProviderInfo.tabsInTypes.datasetsTab.has(data[1].classid)) { + this.dataProviderInfo.tabs.push({"name": "Research Data", "content": "datasetsTab"}); + } + + if(this.dataProviderInfo.tabsInTypes.projectsTab.has(data[1].classid)) { + this.dataProviderInfo.tabs.push({"name": "Projects", "content": "projectsTab"}); + } + if(this.dataProviderInfo.tabsInTypes.datasourcesTab.has(data[1].classid)) { + this.dataProviderInfo.tabs.push({"name": "Content Providers", "content": "datasourcesTab"}); + } + this.dataProviderInfo.tabs.push({"name": "Organizations", "content": "organizationsTab"}); + + if(this.dataProviderInfo.tabsInTypes.relatedDatasourcesTab.has(data[1].classid)) { + this.dataProviderInfo.tabs.push({"name": "Related Content Providers", "content": "relatedDatasourcesTab"}); + } + + if(this.dataProviderInfo.tabsInTypes.statisticsTab.has(data[1].classid)) { + this.dataProviderInfo.tabs.push({"name": "Statistics", "content": "statisticsTab"}); + } + + this.dataProviderInfo.tabs.push({"name": "Metrics", "content": "metricsTab"}); + + if(this.dataProviderInfo.resultTypes.collectedFrom.has(data[1].classid)) { + this.dataProviderInfo.resultsBy = "collectedFrom"; + } else if(this.dataProviderInfo.resultTypes.hostedBy.has(data[1].classid)) { + this.dataProviderInfo.resultsBy = "hostedBy"; + } + } + + if(!this.dataProviderInfo.registry) { + if(data[2] != null) { + this.dataProviderInfo.compatibility = data[2].classname; + } + + if(data[3] != null) { + let oaiPmhURL: string; + if(Array.isArray(data[3])) { + oaiPmhURL = data[3][0]; + } + else { + oaiPmhURL = data[3]; + } + + if(oaiPmhURL != '' && oaiPmhURL != 'unknown') { + this.dataProviderInfo.oaiPmhURL = oaiPmhURL; + } + } + } + + if(data[4] != null) { + let mydata; + let counter = 0; + let countriesSet: Set; + let length = data[4].length!=undefined ? data[4].length : 1; + + for(let i=0; i(); + this.dataProviderInfo.countries = new Array(); + countriesSet = new Set(); + } + + this.dataProviderInfo.organizations[counter] = {"name": "", "id": ""}; + this.dataProviderInfo.organizations[counter]['name'] = mydata.legalname; + this.dataProviderInfo.organizations[counter]['id'] = /*OpenaireProperties.getsearchLinkToOrganization()+*/mydata['to'].content; + + if(mydata.country != '' && mydata['country'].classname != '') { + if(!countriesSet.has(mydata['country'].classname)) { + this.dataProviderInfo.countries.push(mydata['country'].classname); + countriesSet.add(mydata['country'].classname); + } + } + + counter++; + } + } + } + } + + return this.dataProviderInfo; + } +} diff --git a/landingPages/dataProvider/datasetsTab.component.ts b/landingPages/dataProvider/datasetsTab.component.ts new file mode 100644 index 00000000..d75edae7 --- /dev/null +++ b/landingPages/dataProvider/datasetsTab.component.ts @@ -0,0 +1,48 @@ +import {Component, Input} from '@angular/core'; +import { FetchDatasets } from '../../utils/fetchEntitiesClasses/fetchDatasets.class'; + +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'datasetsTab', + template: ` + + + + + + + ` +}) + +export class DatasetsTabComponent { + @Input() paramsForSearchLink = {}; + @Input() fetchDatasets : FetchDatasets; + public linkToSearchDatasets = ""; + public errorCodes:ErrorCodes = new ErrorCodes(); + + constructor () {} + + ngOnInit() { + this.linkToSearchDatasets = OpenaireProperties.getLinkToAdvancedSearchDatasets(); + } + + ngOnDestroy() {} +} diff --git a/landingPages/dataProvider/datasourcesTab.component.ts b/landingPages/dataProvider/datasourcesTab.component.ts new file mode 100644 index 00000000..4db8adf8 --- /dev/null +++ b/landingPages/dataProvider/datasourcesTab.component.ts @@ -0,0 +1,50 @@ +import {Component, Input} from '@angular/core'; +import { FetchDataproviders } from '../../utils/fetchEntitiesClasses/fetchDataproviders.class'; + +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'datasourcesTab', + template: ` + + + + + + + ` +}) + +export class DatasourcesTabComponent { + + @Input() paramsForSearchLink = {}; + @Input() fetchDataproviders : FetchDataproviders; + public linkToSearchDataproviders = ""; + public errorCodes:ErrorCodes = new ErrorCodes(); + + constructor () {} + + ngOnInit() { + this.linkToSearchDataproviders = OpenaireProperties.getLinkToAdvancedSearchDataProviders(); + } + + ngOnDestroy() {} +} diff --git a/landingPages/dataProvider/organizationsTab.component.ts b/landingPages/dataProvider/organizationsTab.component.ts new file mode 100644 index 00000000..0acc97d2 --- /dev/null +++ b/landingPages/dataProvider/organizationsTab.component.ts @@ -0,0 +1,54 @@ +import {Component, Input} from '@angular/core'; + +@Component({ + selector: 'organizationsTab', + template: ` + + +
+
+ {{organizations.length}} organizations, page {{organizationsPage}} of {{totalPages(organizations.length)}} + +
+ +
+

+ + + {{item['name']}} + +

+

+ {{item['name']}} +

+
+
+ ` +}) + +export class OrganizationsTabComponent { + + @Input() organizations: {"name": string, "id": string}[]; + public organizationsPage: number = 1; + public pageSize: number = 10; + + constructor () {} + + ngOnInit() {} + + ngOnDestroy() {} + + totalPages(totalResults: number): number { + let totalPages:any = totalResults/this.pageSize; + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, this.pageSize) + 1); + } + return totalPages; + } + + updateOrganizationsPage($event) { + this.organizationsPage = $event.value; + } +} diff --git a/landingPages/dataProvider/projectsTab.component.ts b/landingPages/dataProvider/projectsTab.component.ts new file mode 100644 index 00000000..4102e285 --- /dev/null +++ b/landingPages/dataProvider/projectsTab.component.ts @@ -0,0 +1,49 @@ +import {Component, Input} from '@angular/core'; + +import { FetchProjects } from '../../utils/fetchEntitiesClasses/fetchProjects.class'; + +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'projectsTab', + template: ` + + + + + + + ` +}) + +export class ProjectsTabComponent { + + @Input() paramsForSearchLink = {}; + @Input() fetchProjects : FetchProjects; + public linkToSearchProjects = ""; + public errorCodes:ErrorCodes = new ErrorCodes(); + + constructor () {} + + ngOnInit() { + this.linkToSearchProjects = OpenaireProperties.getLinkToAdvancedSearchProjects(); + } + + ngOnDestroy() {} +} diff --git a/landingPages/dataProvider/publicationsTab.component.ts b/landingPages/dataProvider/publicationsTab.component.ts new file mode 100644 index 00000000..156e48e6 --- /dev/null +++ b/landingPages/dataProvider/publicationsTab.component.ts @@ -0,0 +1,50 @@ +import {Component, Input} from '@angular/core'; +import { FetchPublications } from '../../utils/fetchEntitiesClasses/fetchPublications.class'; + +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'publicationsTab', + template: ` + + + + + + + + + ` +}) + +export class PublicationsTabComponent { + @Input() paramsForSearchLink = {};//: string = ""; + @Input() fetchPublications : FetchPublications; + public linkToSearchPublications = ""; + public errorCodes:ErrorCodes = new ErrorCodes(); + + constructor () {} + + ngOnInit() { + this.linkToSearchPublications = OpenaireProperties.getLinkToAdvancedSearchPublications();//+this.paramsForSearchLink; + } + + ngOnDestroy() {} +} diff --git a/landingPages/dataProvider/relatedDatasourcesTab.component.ts b/landingPages/dataProvider/relatedDatasourcesTab.component.ts new file mode 100644 index 00000000..da85f597 --- /dev/null +++ b/landingPages/dataProvider/relatedDatasourcesTab.component.ts @@ -0,0 +1,122 @@ +import {Component, Input} from '@angular/core'; + +import { FetchPublications } from '../../utils/fetchEntitiesClasses/fetchPublications.class'; +import { FetchDatasets } from '../../utils/fetchEntitiesClasses/fetchDatasets.class'; + +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../utils/routerHelper.class'; +import { Observable } from 'rxjs/Observable'; + +@Component({ + selector: 'relatedDatasourcesTab', + template: ` + + + + + + +
+
+ {{results.size}} related content providers, page {{page}} of {{totalPages(results.size)}} + +
+ + + + + + + + + + + + + + + + + + + + + + + +
Content Provider Name + Number of Publications + + Number of Research Data +
+ + {{results.get(id).name}} + + + + {{results.get(id).countPublications}} + + - + + {{results.get(id).countDatasets}} + + -
+
+ ` +}) + +export class RelatedDatasourcesTabComponent { + @Input() dataproviderId: string; + @Input() fetchPublications : FetchPublications; + @Input() fetchDatasets : FetchDatasets; + // true: preprocessing is not over + @Input() loading: boolean = true; + // Εvery content provider's id is a single key of a map + @Input() results: Map; + + public linkToSearchPublications: string = ""; + public linkToSearchResearchData: string = ""; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + public page: number = 1; + public pageSize: number = 10; + + constructor () {} + + ngOnInit() { + this.linkToSearchPublications = OpenaireProperties.getLinkToAdvancedSearchPublications();//+"?&hostedBy=";//+ +"&ho=and&collectedFrom="+ +"&co=and"; + this.linkToSearchResearchData = OpenaireProperties.getLinkToAdvancedSearchDatasets(); + } + + ngOnDestroy() {} + + totalPages(totalResults: number): number { + let totalPages:any = totalResults/this.pageSize; + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, this.pageSize) + 1); + } + return totalPages; + } + + updatePage($event) { + this.page = $event.value; + } +} diff --git a/landingPages/dataProvider/statisticsTab.component.ts b/landingPages/dataProvider/statisticsTab.component.ts new file mode 100644 index 00000000..4aae1f91 --- /dev/null +++ b/landingPages/dataProvider/statisticsTab.component.ts @@ -0,0 +1,78 @@ +import {Component, Input} from '@angular/core'; +import { SearchDatasetsComponent } from '../../searchPages/simple/searchDatasets.component'; +import { SearchPublicationsComponent } from '../../searchPages/simple/searchPublications.component'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'statisticsTab', + template: ` +
+ + + + +
+

Latest Documents Timeline

+ +

Documents Types

+ +
+ + +
+
+

Funders in content providers Publications

+ +

Projects with most Publications

+ + +
+
+
+

Projects with most Research Data

+ + +
+
+
+
+ ` +}) + +export class StatisticsTabComponent { + + @Input() statistics; + @Input() id; + @Input() searchDatasetsComponent : SearchDatasetsComponent; + @Input() searchPublicationsComponent : SearchPublicationsComponent; + @Input() show : boolean = false; + + private docsTimelineUrl: string; + private docsTypesUrl:string; + private docsFunderUrl:string; + private dataProjectsUrl:string ; + private pubsProjectsUrl:string; + public errorCodes:ErrorCodes = new ErrorCodes(); + + constructor () {} + + ngOnInit() { + + this.docsTimelineUrl ='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcYear","dtsrcName":"'+this.id+'","table": "result", "fields": [{"fld": "number", "agg": "count", "type": "line", "yaxis":1, "c":true}], "xaxis":{"name": "year", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Documents"], "in": [{"f":0, "text": "Yearly"}], "filters": [{"name":"year","max":"2016","min":"1997"},{"name": "result_datasources-datasource-name", "values":[""], "to": "-1"}],"having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": "Year"}&w=600&h=250'; + this.docsTypesUrl = 'https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcPubs","dtsrcName":"'+this.id+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "pie", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Documents"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.docsFunderUrl =' https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcPubsFund","dtsrcName":"'+this.id+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "pie", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Documents"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.dataProjectsUrl ='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcProjData","dtsrcName":"'+this.id+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "bar", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Datasets"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.pubsProjectsUrl ='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"dtsrcProjPubs","dtsrcName":"'+this.id+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "bar", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Publications"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [""], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + } + + ngOnDestroy() {} +} diff --git a/landingPages/dataset/dataset-routing.module.ts b/landingPages/dataset/dataset-routing.module.ts new file mode 100644 index 00000000..4b9372a4 --- /dev/null +++ b/landingPages/dataset/dataset-routing.module.ts @@ -0,0 +1,18 @@ +// import { NgModule } from '@angular/core'; +// import { RouterModule } from '@angular/router'; +// +// import { DatasetComponent } from './dataset.component'; +// import {FreeGuard} from'../../login/freeGuard.guard'; +// import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +// import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; +// +// @NgModule({ +// imports: [ +// RouterModule.forChild([ +// { path: '', component: DatasetComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { +// redirect: '/error' +// },canDeactivate: [PreviousRouteRecorder] } +// ]) +// ] +// }) +// export class DatasetRoutingModule { } diff --git a/landingPages/dataset/dataset.component.html b/landingPages/dataset/dataset.component.html new file mode 100644 index 00000000..f14ec667 --- /dev/null +++ b/landingPages/dataset/dataset.component.html @@ -0,0 +1,292 @@ +
+
+
+ +
+ + + + + +
+
+ + {{datasetInfo.types.join(", ")}} + {{datasetInfo.languages.join(", ")}} + + {{datasetInfo.title.accessMode}} + + + Record in preview + + + + +
+ + ({{datasetInfo.date}}) +
+ +
    +
  • Publisher: {{datasetInfo.publisher}}
  • + +
  • Embargo end date: {{datasetInfo.embargoEndDate}}
  • +
  • + +
  • +
  • + + +
  • +
+ +
+ {{datasetInfo.description}} +
+ + + + + + + + + + + +
+
+
+ No related research results available +
+
+ +
+
{{provenanceaction}}
+ + +
+
+
+ +
+
+ No similar research results available +
+
+ +
+
+
+ + + + + + + +
+ +
+
+ +
+
+
+ Share - Bookmark + +
+ + +
    + +
  • + +
  • +
  • + +
  • + +
  • +
    +
    Related to
    +
    + + {{item['labelContext']}} + -> {{item['labelCategory']}} + : {{item['labelConcept']}} + + + {{item['labelContext']}} + -> {{item['labelCategory']}} + : {{item['labelConcept']}} + +
    + +
    + +
  • + +
  • +
      +
    • +
      + Cite this reasearch data +
      +
      + +
      +
    • +
    +
  • +
  • + + +
  • + + +
+ + +
+
+
+
+
+
+
diff --git a/landingPages/dataset/dataset.component.ts b/landingPages/dataset/dataset.component.ts new file mode 100644 index 00000000..b1c5829b --- /dev/null +++ b/landingPages/dataset/dataset.component.ts @@ -0,0 +1,172 @@ +import {Component, ViewChild, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {DatasetService} from './dataset.service'; +import {DatasetInfo} from '../../utils/entities/datasetInfo'; +import {ActivatedRoute, Router} from '@angular/router'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties' +import {RouterHelper} from '../../utils/routerHelper.class'; +import { Meta} from '../../../angular2-meta'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'dataset', + templateUrl: 'dataset.component.html', +}) + +export class DatasetComponent { + public datasetInfo: DatasetInfo; + public datasetId : string ; + + // APP BOX variables + public showAllCollectedFrom: boolean = false; + public showAllDownloadFrom: boolean = false; + public showAllPublishedIn: boolean = false; + + // Metrics tab variables + public metricsClicked: boolean; + public viewsFrameUrl: string; + public downloadsFrameUrl: string; + public totalViews: number; + public totalDownloads: number; + public pageViews: number; + + // Active tab variable for responsiveness + public activeTab: string = "Related Research Results"; + + // Map counting variable + public relatedResearchResultsNum: number = 0; + + // Message variables + public warningMessage = ""; + public errorMessage = ""; + public showLoading: boolean = true; + + public routerHelper:RouterHelper = new RouterHelper(); + + private result ; + sub: any; piwiksub: any; infoSub: any; + + constructor (private element: ElementRef, + private _datasetService: DatasetService, + private _piwikService:PiwikService, + private route: ActivatedRoute, + private _meta: Meta, + private _router: Router) { + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + this.datasetInfo = null; + this.updateTitle("Dataset"); + this.updateDescription("Dataset, search, open access"); + + this.datasetId = params['datasetId']; + console.info("Id is :"+this.datasetId); + + if(this.datasetId){ + this.getDatasetInfo(this.datasetId); + }else{ + this.showLoading = false; + this.warningMessage="No valid research data id"; + } + + this.metricsClicked = false; + + this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoViews", "resTitle":"'+this.datasetId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":" ","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"Repository","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false'; + /*this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resViewsTimeline", "resTitle":"'+this.datasetId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":" ","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"Repository","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(124, 181, 236, 1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false'; + */ + + this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoDownloads", "resTitle":"'+this.datasetId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":" ","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"Repository","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false'; + /*this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoDownloadTimeline", "resTitle":"'+this.datasetId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":" ","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"Repository","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true'; + */ + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + }); + + } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.infoSub) { + this.infoSub.unsubscribe(); + } + } + + private getDatasetInfo(id:string) { + this.warningMessage = ''; + this.errorMessage="" + this.showLoading = true; + + this.infoSub = this._datasetService.getDatasetInfo(id).subscribe( + data => { + this.datasetInfo = data; + this.updateTitle(this.datasetInfo.title.name); + this.updateDescription("Dataset, search, repositories, open access,"+this.datasetInfo.title.name); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.datasetInfo.title.name).subscribe(); + } + + this.result = [] + this.result = {id: id, type :"dataset", source : "openaire", title: this.datasetInfo.title,url: '', result: '', accessRights: this.datasetInfo.title.accessMode, embargoEndDate: ''}; + + let relatedResearchResultsNum = 0; + if(this.datasetInfo.relatedResearchResults != undefined) { + this.datasetInfo.relatedResearchResults.forEach(function (value, key, map) { + relatedResearchResultsNum += value.length; + }); + } + this.relatedResearchResultsNum = relatedResearchResultsNum; + + this.showLoading = false; + }, + err => { + console.log(err) + console.info("error"); + + this.errorMessage = 'No research data found'; + this.showLoading = false; + } + ); + } + + // showChange($event) { + // this.showAllReferences=$event.value; + // } + + public metricsResults($event) { + this.totalViews = $event.totalViews; + this.totalDownloads = $event.totalDownloads; + this.pageViews = $event.pageViews; + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + public buildCurationTooltip() { + let tooltipContent: string = "
"; + + tooltipContent += "

Record in preview

"; + tooltipContent += "

Bibliographic record accepted by the system, but not yet processed by
OpenAIRE tools for information quality improvement and de-duplication

"; + + return tooltipContent; + } + public getKeys( map) { + return Array.from(map.keys()); + } +} diff --git a/landingPages/dataset/dataset.module.ts b/landingPages/dataset/dataset.module.ts new file mode 100644 index 00000000..8aeb5940 --- /dev/null +++ b/landingPages/dataset/dataset.module.ts @@ -0,0 +1,42 @@ +//import {MaterialModule} from '@angular/material'; +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { SharedModule } from '../../shared/shared.module'; +import { RouterModule } from '@angular/router'; + +import { DatasetService} from './dataset.service'; +import { DatasetComponent } from './dataset.component'; +// import { DatasetRoutingModule } from './dataset-routing.module'; +import {MetricsModule} from '../landing-utils/metrics.module'; +import {IFrameModule} from '../../utils/iframe.module'; +import {AltMetricsModule} from '../../utils/altmetrics.module'; +import {CiteThisModule} from '../landing-utils/citeThis/citeThis.module'; + +import { ResultLandingModule } from '../landing-utils/resultLanding.module'; +import { LandingModule } from '../landing-utils/landing.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +import {MetaModule} from '../../../meta.module'; +import { ConfigurationServiceModule } from '../../utils/configuration/configurationService.module'; + + +@NgModule({ + imports: [ + //MaterialModule.forRoot(), + CommonModule, FormsModule,SharedModule, RouterModule, LandingModule, CiteThisModule, + ResultLandingModule, MetricsModule, IFrameModule, AltMetricsModule, + MetaModule, ConfigurationServiceModule + ], + declarations: [ + DatasetComponent + ], + providers:[ + DatasetService, FreeGuard, IsRouteEnabled + ], + exports: [ + DatasetComponent + ] +}) +export class DatasetModule { } diff --git a/landingPages/dataset/dataset.service.ts b/landingPages/dataset/dataset.service.ts new file mode 100644 index 00000000..a6328f2e --- /dev/null +++ b/landingPages/dataset/dataset.service.ts @@ -0,0 +1,195 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {DatasetInfo} from '../../utils/entities/datasetInfo'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + +import { ParsingFunctions } from '../landing-utils/parsingFunctions.class'; + +@Injectable() +export class DatasetService { + + constructor(private http: Http ) { + this.parsingFunctions = new ParsingFunctions(); + } + + public parsingFunctions: ParsingFunctions; + datasetInfo: DatasetInfo; + + getDatasetInfo (id: string):any { + console.info("getDatasetInfo in service"); + + let url = OpenaireProperties. getSearchAPIURLLast()+'datasets/'+id+"?format=json"; + let key = url; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .do(res => console.info(res['result']['metadata']['oaf:entity'])) + .map(res => [res['result']['header']['dri:status'], res['result']['metadata']['oaf:entity']['oaf:result']]) + .map(res => [res[1], + res[1]['title'], + res[1]['rels']['rel'], + res[1]['children'], + res[1]['pid'], + res[1]['subject'], + res[1]['bestaccessright'], + res[1]['collectedfrom'], + res[1]['context'], + //res[1]['resulttype'], + res[0], + res[1]['creator'] + ]).map(res => this.parseDatasetInfo(res)); + } + + 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.log(error); + return Observable.throw(error || 'Server error'); + } + + parseDatasetInfo (data: any):any { + this.datasetInfo = new DatasetInfo(); + + if(data[0] != null) { + var date:string = (data[0].dateofacceptance)+""; // transform to string in case it is an integer + this.datasetInfo.date = (date && (date).indexOf('-') !== -1)?date.split('-')[0]:date; + this.datasetInfo.dateofacceptance = data[0].dateofacceptance; + this.datasetInfo.publisher = data[0].publisher; + if(!Array.isArray(data[0].description)) { + this.datasetInfo.description = data[0].description; + } else { + this.datasetInfo.description = data[0].description[0]; + } + this.datasetInfo.embargoEndDate = data[0].embargoenddate; + } + this.datasetInfo.title = {"name": "", "url": "", "accessMode": ""}; + if(data[0]['bestaccessright'].hasOwnProperty("classid")) { + this.datasetInfo.title.accessMode = data[0]['bestaccessright'].classid; + } + if(data[1] != null) { + if(Array.isArray(data[1])) { + this.datasetInfo.title['name'] = data[1][0].content; + } else { + this.datasetInfo.title['name'] = data[1].content; + } + } + + if(data[2] != null) { + let relation; + let length = data[2].length!=undefined ? data[2].length : 1; + + for(let i=0; i(); + + this.datasetInfo.types = new Array(); + let types = new Set(); + + let counter = 0; + let instance; + + let length = data[3]['instance'].length!=undefined ? data[3]['instance'].length : 1; + + for(let i=0; i, Map] = this.parsingFunctions.parseAllSubjects(data[5]); + this.datasetInfo.subjects = subjectResults[0]; + this.datasetInfo.otherSubjects = subjectResults[1]; + this.datasetInfo.classifiedSubjects = subjectResults[2]; + } + + this.datasetInfo.hostedBy_collectedFrom = this.parsingFunctions.addPublisherToHostedBy_collectedFrom( + this.datasetInfo.hostedBy_collectedFrom, this.datasetInfo.publisher, + null, this.datasetInfo.identifiers, this.datasetInfo.title); + + if(data[8] != null) { + this.datasetInfo.contexts = this.parsingFunctions.parseContexts(data[8]); + } + + // if(data[9] != null && this.datasetInfo.type == undefined) { + // if(data[9].hasOwnProperty('classname')) { + // this.datasetInfo.type = data[9].classname; + // } + // } + + if(data[9] != null && data[9] == "under curation") { + this.datasetInfo.underCurationMessage = true; + } else { + this.datasetInfo.underCurationMessage = false; + } + + if(data[10] != null) { + if(this.datasetInfo.authors == undefined) { + this.datasetInfo.authors = new Array(); + } + + let authors = data[10]; + let length = Array.isArray(authors) ? authors.length : 1; + for(let i=0; i +
+
+ +
+ + + +
+

{{header1}}

+

{{header2}}

+ +
+ +
+ +
+ + +
+
+
+
+
+ + ` + }) +export class HtmlProjectReportComponent{ + private projectId: string; + private totalResults: number = 10; + private resultsType: string = "publication"; + + public header1: string = ""; + public header2: string = ""; + public htmlResult: string = ""; + + public sub: any; piwiksub: any; + public subHTML: any; + public subHTMLInfo: any; + + public warningMessage: string = ""; + public errorMessage: string = ""; + public showLoading: boolean = true; + + constructor ( private route: ActivatedRoute, + private htmlService: HtmlProjectReportService, + private _piwikService:PiwikService, + private _projectService: ProjectService, + private _meta: Meta, private _router: Router) { + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + this.projectId = params['projectId']; + + if (params['size'] == parseInt(params['size'], 10)) { + this.totalResults = params['size']; + } else { + this.showLoading = false; + this.warningMessage="Requested size is not an integer"; + } + + if(params['type'] && (params['type'] == "publication" || params['type'] == "dataset" || params['type'] == "software")){ + if(params['type'] == "publication") { + this.resultsType = 'publication'; + } else if(params['type'] == "dataset") { + this.resultsType = 'research data'; + } else if(params['type'] == "software") { + this.resultsType = 'software'; + } + + this.updateTitle("Project's "+this.resultsType+" report"); + this.updateDescription("project, project "+ this.resultsType +" report, funding, open access, publications, research data, software"); + } else { + this.showLoading = false; + this.warningMessage="Requested type should be publication or research data or software"; + } + + //showLoading is true if no warnings + if(this.showLoading) { + if(this.projectId) { + this.createHeaders(); + } else { + this.showLoading = false; + this.warningMessage="No valid project id"; + } + } + }); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.subHTML) { + this.subHTML.unsubscribe(); + } + if(this.subHTMLInfo) { + this.subHTMLInfo.unsubscribe(); + } + } + + private createHeaders() { + this.subHTMLInfo = this._projectService.getHTMLInfo(this.projectId).subscribe( + data => { + this.createHeader1(data); + if(data.acronym) { + this.updateTitle(data.acronym+" "+this.resultsType+" report"); + } else if(data.title){ + this.updateTitle(data.title+" "+this.resultsType+" report"); + } + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(((data.acronym)?data.acronym:data.title)+" "+this.resultsType+" report").subscribe(); + } + }, + err => { + console.log(err); + this.createClipboard(); + } + ); + + if(this.resultsType == "publication") { + this.header2 += this.totalResults + " publications"; + } else if(this.resultsType == "research data") { + this.header2 += this.totalResults + " research data"; + } else if(this.resultsType == "software") { + this.header2 += this.totalResults + " software"; + } + } + + private createClipboard() { + let intro: string = ''; + intro += ''; + intro += ''; + intro += ''+this.header1+'' + intro += ''; + + if (typeof window !== 'undefined') { + this.subHTML = this.htmlService.getHTML(this.projectId, this.totalResults, this.resultsType).subscribe( + data => { + let body: string = intro+'

'+this.header1+'

'+this.header2+'

'+data+''; + this.htmlResult = data; + + let clipboard; + let Clipboard; + Clipboard = require('clipboard'); + clipboard = new Clipboard('.clipBtn', { + /*target: function(trigger) { + return document.getElementById("clipboard"); + }*/ + text: function(trigger) { + return body;//document.getElementById("clipboard").getAttribute('innerHTML');//"aaaa"+tmp+"oo"; + } + }); + + this.showLoading = false; + }, + err => { + console.log(err); + this.errorMessage = 'Service not available'; + this.showLoading = false; + } + ); + } + } + + createHeader1(data: {"title": string, "acronym": string, "callIdentifier": string}) { + if(this.resultsType == "publication") { + this.header1 += "Publications"; + } else if(this.resultsType == "research data") { + this.header1 += "Research Data"; + } else if(this.resultsType == "software") { + this.header1 += "Software"; + } + + if(data != undefined) { + if(data.title != undefined && data.title != "") { + this.header1 += data.title; + } + if((data.title != undefined && data.title != "") && + ((data.acronym != undefined && data.acronym != "") || + (data.callIdentifier != undefined && data.callIdentifier != ""))) { + this.header1 += "("; + } + if(data.acronym != undefined && data.acronym != "") { + this.header1 += data.acronym + " - "; + } + if(data.callIdentifier != undefined && data.callIdentifier != "") { + this.header1 += data.callIdentifier; + } + if((data.title != undefined && data.title != "") && + ((data.acronym != undefined && data.acronym != "") || + (data.callIdentifier != undefined && data.callIdentifier != ""))) { + this.header1 += ")"; + } + } + + this.createClipboard(); + } + + public copied() { + UIkit.notification({ + message : 'Raw html is copied. Please paste it on an html file.', + status : 'success', + timeout : 3000, + pos : 'top-center' + }); + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } +} diff --git a/landingPages/htmlProjectReport/htmlProjectReport.module.ts b/landingPages/htmlProjectReport/htmlProjectReport.module.ts new file mode 100644 index 00000000..fde02fac --- /dev/null +++ b/landingPages/htmlProjectReport/htmlProjectReport.module.ts @@ -0,0 +1,28 @@ +//import {MaterialModule} from '@angular/material'; +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { ProjectServiceModule} from '../project/projectService.module'; + + +import {HtmlProjectReportService} from './htmlProjectReport.service'; +import {HtmlProjectReportComponent} from './htmlProjectReport.component'; +// import { HtmlProjectReportRoutingModule } from './htmlProjectReport-routing.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, ProjectServiceModule,PiwikServiceModule + ], + declarations: [ + HtmlProjectReportComponent + ], + providers:[ + HtmlProjectReportService, FreeGuard + ], + exports: [ + HtmlProjectReportComponent + ] +}) +export class HtmlProjectReportModule { } diff --git a/landingPages/htmlProjectReport/htmlProjectReport.service.ts b/landingPages/htmlProjectReport/htmlProjectReport.service.ts new file mode 100644 index 00000000..c044af95 --- /dev/null +++ b/landingPages/htmlProjectReport/htmlProjectReport.service.ts @@ -0,0 +1,36 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/operator/do'; + +@Injectable() +export class HtmlProjectReportService { + + constructor(private http: Http ) {} + + getHTML(id: string, size: number, type:string):any { + console.info("getHTML in service"); + + let resultTypeId: string; + let requestType: string; + if(type == "publication") { + resultTypeId = 'publication'; + requestType = 'publications'; + } else if(type == "research data") { + resultTypeId = 'dataset'; + requestType = 'datasets'; + } else if(type == "software") { + resultTypeId = 'software'; + requestType = 'software' + } + + //let url = OpenaireProperties. getSearchAPIURLLast() + 'publications/' +id+"?format=json"; + let url = OpenaireProperties.getCsvAPIURL(); + url += 'resources?format=html&page=0&size='+size+'&type='+requestType+'&query=(((oaftype exact result) and (resulttypeid exact '+resultTypeId+')) and (relprojectid exact "'+id+'"))'; + let key = url; + + return this.http.get(url) + .map(res => res.text()); + } +} diff --git a/landingPages/landing-utils/addThis.component.ts b/landingPages/landing-utils/addThis.component.ts new file mode 100644 index 00000000..b17d1cae --- /dev/null +++ b/landingPages/landing-utils/addThis.component.ts @@ -0,0 +1,43 @@ +import {Component, ElementRef, Input} from '@angular/core'; +import {ActivatedRoute} from '@angular/router'; + + interface addthis { + layers: refresh; + init: Function; + } + interface refresh { + refresh: Function; + } + declare var addthis: addthis; + +// +@Component({ + selector: 'addThis', + template: ` +
+ ` +}) +export class AddThisComponent { + private sub:any; + + + constructor(private route: ActivatedRoute) { + + } + ngOnInit() { + this.sub = this.route.queryParams.subscribe(data => { + + if (typeof document !== 'undefined') { + try{ + addthis.init(); + addthis.layers.refresh(); + }catch (e) { + console.log(e); + } + } + }); + + } + + +} diff --git a/landingPages/landing-utils/availableOn.component.ts b/landingPages/landing-utils/availableOn.component.ts new file mode 100644 index 00000000..40b1baab --- /dev/null +++ b/landingPages/landing-utils/availableOn.component.ts @@ -0,0 +1,73 @@ +import {Component, Input, ElementRef} from '@angular/core'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'availableOn', + template: ` +
+
Available On
+
+
+
+ + {{available.downloadName}} + + + [{{i+1}}] + + + + + {{available.downloadName}} + + via + + {{available.collectedName}} + + ({{available.type}}, {{available.year}}) +
+
+
+
+ + View less + +
+
...
+
+ + View more + +
+
+ ` + }) + +export class AvailableOnComponent { + @Input() availableOn: { "downloadName": string, "downloadUrl": string[], + "collectedName": string, "collectedId": string, + "accessMode": string[], "bestAccessMode": string, + "type": string, "year":string }[]; + + public showAll: boolean = false; + + constructor (private element: ElementRef) {} + + ngOnInit() {} + + public scroll() { + console.info("scroll into view"); + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + } +} diff --git a/landingPages/landing-utils/citeThis/citation.class.ts b/landingPages/landing-utils/citeThis/citation.class.ts new file mode 100644 index 00000000..b1367230 --- /dev/null +++ b/landingPages/landing-utils/citeThis/citation.class.ts @@ -0,0 +1,31 @@ +export class Citation{ + public templates:string[]=["bibtex","chicago","ieee","science","apa","cell","harvard","mla","nature","acm"]; + + bibtex:string =` `; + ieee:string =` `; + chicago:string =` `; + science:string =' '; + cell:string =' '; + mla:string =' '; + nature:string =' '; +//nature_csl:string =' '; + acm:string =' '; + apa:string =' '; + harvard:string = ' '; + locale:string =' This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License 2012-07-04T23:31:02+00:00 radio broadcast television broadcast podcast instant message email volume volumes accessed and & and others anonymous anon. at available at by circa c. cited edition editions ed. et al. forthcoming from ibid. in in press internet interview letter no date n.d. online presented at the reference references ref. refs. retrieved scale version AD BC th st nd rd th th th first second third fourth fifth sixth seventh eighth ninth tenth book books chapter chapters column columns figure figures folio folios number numbers line lines note notes opus opera page pages paragraph paragraph part parts section sections sub verbo sub verbis verse verses volume volumes bk. chap. col. fig. f. no. l. n. op. p. pp. para. pt. sec. s.v. s.vv. v. vv. vol. vols. ¶¶ § §§ director directors editor editors editor editors illustrator illustrators translator translators editor & translator editors & translators dir. dirs. ed. eds. ed. eds. ill. ills. tran. trans. ed. & tran. eds. & trans. directed by edited by edited by illustrated by interview by to by translated by edited & translated by by dir. ed. ed. illus. trans. ed. & trans. January February March April May June July August September October November December Jan. Feb. Mar. Apr. May Jun. Jul. Aug. Sep. Oct. Nov. Dec. Spring Summer Autumn Winter '; + + +} +export class CitationData{ + public id:string; + public type:string; + public title:string; + public DOI:string; + public "container-title":string; + public publisher:string; + public author:{given:string, family:string, 'parse-names':boolean}[] =[]; + public issued ={};//{"date-parts":string[]}[] =[]; + public date:string; + public authors:string[] =[]; + +} diff --git a/landingPages/landing-utils/citeThis/citeThis.component.ts b/landingPages/landing-utils/citeThis/citeThis.component.ts new file mode 100644 index 00000000..91fbac4b --- /dev/null +++ b/landingPages/landing-utils/citeThis/citeThis.component.ts @@ -0,0 +1,127 @@ +import {Component, ElementRef, Input} from '@angular/core'; +import {ActivatedRoute} from '@angular/router'; +import {Citation, CitationData} from './citation.class'; +declare var CSL:any; +declare var Sys:any; +// +@Component({ + selector: 'citeThis', + template: ` + +
+
+ +
+ +
+
+
+
+ ` +}) +export class CiteThisComponent { + private sub:any; + public selectedStyle:string; + public citationText:string; + public citation:Citation = new Citation(); + // public cite: any; + @Input() result: any; + @Input() id: string; + @Input() type: string="article"; + public citeproc; + public data; + + + constructor(private route: ActivatedRoute) { + this.selectedStyle = this.citation.templates[0]; + } + + ngOnInit() { + if(typeof window !== 'undefined') { + // this.citeproc = require('./citeproc.js'); + // console.log(this.citeproc); + this.parseData(); + this.updateCitation(); + } + } + parseData(){ + var citationData:CitationData = new CitationData(); + + citationData.id = this.id; + if(this.result.types != undefined && this.result.types.length > 0 && this.result.types[0]){ + citationData.type = this.result.types[0].toLowerCase(); + }else if(this.result.type != undefined ){ + citationData.type = this.result.type.toLowerCase(); + } + if(this.result.title && this.result.title.name){ + citationData.title = this.result.title.name; + } + if(this.result.journal && this.result.journal.journal){ + citationData["container-title"] = this.result.journal.journal; + } + if(this.result.publisher){ + citationData.publisher = this.result.publisher; + } + if( this.result.authors){ + citationData.author = []; + var max_length = (this.result.authors.length > 10)?10:this.result.authors.length; + for (var i =0 ;i < max_length; i++){ + if(this.result.authors[i] && this.result.authors[i].indexOf(", ") !== -1){ + citationData.author.push({given:this.result.authors[i].split(", ")[0], family:this.result.authors[i].split(", ")[1], 'parse-names':true}); + }else{ + citationData.author.push({given:"", family:this.result.authors[i], 'parse-names':true}); + } + // citationData.authors.push(this.result.authors[i]); + } + } + if(this.result.dateofacceptance != undefined){ + citationData.issued = {}; + var date:string = (this.result.dateofacceptance)+""; // transform to string in case it is an integer + var dateArray:string[] = (date && (date).indexOf('-') !== -1)?date.split('-'):[date]; + if(dateArray.length < 3){ + // dateArray.push[1]; + // dateArray.push[1]; + } + citationData.issued={"date-parts":[[""+dateArray[0],dateArray[1], dateArray[2]]]}; + if(this.result.date ){ + citationData.date = this.result.date ; + } + } + + + this.data = citationData; + // console.log(this.data); + + } + styleChanged(){ + this.updateCitation(); + + } + updateCitation(){ + var Sys = + function Sys(lang, data){ + this.lang = lang; + this.data = data; + this.changeName = function (name) { + this.lastName = name; + }; + this.retrieveLocale= function (lang){ + + return this.lang; + } + this.retrieveItem= function(id){ + console.log("retrieve id:" + id); + return this.data; + } + }; + + var citeproc = new CSL.Engine(new Sys(this.citation.locale, this.data ), this.citation[this.selectedStyle]); + citeproc.updateItems([this.data.id]); + this.citationText = citeproc.makeBibliography(); + this.citationText = ((this.citationText != null) && (this.citationText.length > 1) && (this.citationText[1].length > 0)) ? this.citationText[1][0] : ''; + + } + +} diff --git a/landingPages/landing-utils/citeThis/citeThis.module.ts b/landingPages/landing-utils/citeThis/citeThis.module.ts new file mode 100644 index 00000000..4a14a36a --- /dev/null +++ b/landingPages/landing-utils/citeThis/citeThis.module.ts @@ -0,0 +1,23 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + + import {CiteThisComponent} from './citeThis.component'; + +@NgModule({ + imports: [ + + CommonModule, FormsModule + ], + declarations: [ + CiteThisComponent + ], + providers:[ + + ], + exports: [ + + CiteThisComponent + ] +}) +export class CiteThisModule { } diff --git a/landingPages/landing-utils/fundedBy.component.ts b/landingPages/landing-utils/fundedBy.component.ts new file mode 100644 index 00000000..885ad549 --- /dev/null +++ b/landingPages/landing-utils/fundedBy.component.ts @@ -0,0 +1,131 @@ +import {Component, Input, ElementRef} from '@angular/core'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'fundedBy', + template: ` +
+
Funded By
+
+
+ + + + {{item['funderShortname']?item['funderShortname']:item['funderName']}} + [no funder available] + | {{ item['acronym']?item['acronym']:item['title']}} + + + + + {{item['funderShortname']?item['funderShortname']:item['funderName']}} + [no funder available] + | {{ item['acronym']?item['acronym']:item['title']}} + + + + + {{item['funderShortname']?item['funderShortname']:item['funderName']}} + [no funder available] + | {{ item['acronym']?item['acronym']:item['title']}} + + + + + {{item['funderShortname']?item['funderShortname']:item['funderName']}} + [no funder available] + | {{ item['acronym']?item['acronym']:item['title']}} + + + + + + + +
+
+
+ + View less + +
+
...
+
+ + View more + +
+
+ ` + }) + +export class FundedByComponent { + @Input() fundedByProjects: { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "funding": string, "code": string, "provenanceAction": string, + "inline": boolean }[]; + public showAll: boolean = false; + + constructor (private element: ElementRef) {} + + ngOnInit() {} + + public buildFundingTooltip(item: { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "funding": string, "code": string, "provenanceAction": string, inline: boolean}) { + let tooltipContent: string = "
"; + + if(item.title) { + tooltipContent += "
"+item.title+"
"; + } + + if(item.code || item.funderName || item.funderShortname || item.funding) { + tooltipContent += "

"; + } + + if(item.code) { + tooltipContent += "

Project Code: "+item.code+"
"; + } + if(item.funderName || item.funderShortname) { + tooltipContent += "
Funder: "; + if(item.funderName && item.funderShortname) { + tooltipContent += item.funderName + " ("+ item.funderShortname +")"; + } else if(item.funderName) { + tooltipContent += item.funderName; + } else { + tooltipContent += item.funderShortname; + } + tooltipContent += "
"; + } + + if(item.funding) { + tooltipContent += "
Funding: "+ item.funding + "
"; + } + + if(item.code || item.funderName || item.funderShortname || item.funding) { + tooltipContent += "

"; + } + + if(item.provenanceAction == 'Repository') { + tooltipContent += "Provided by Repository"; + } else if(item.provenanceAction == 'OpenAIRE') { + tooltipContent += "Inferred by OpenAIRE"; + } else if(item.provenanceAction == 'USer') { + tooltipContent += "Claimed by User"; + } + + tooltipContent+="
" + return tooltipContent; + } + + public scroll() { + console.info("scroll into view"); + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + } +} diff --git a/landingPages/landing-utils/landing.module.ts b/landingPages/landing-utils/landing.module.ts new file mode 100644 index 00000000..a7ae76f1 --- /dev/null +++ b/landingPages/landing-utils/landing.module.ts @@ -0,0 +1,28 @@ +/* This module contains all common components for all landing pages */ + +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {TabPagingComponent} from './tabPaging.component'; +import {ShowTitleComponent} from './showTitle.component'; +import {AddThisComponent} from './addThis.component'; +import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; +import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, PiwikServiceModule + ], + declarations: [ + TabPagingComponent, ShowTitleComponent, AddThisComponent + ], + providers:[ + PreviousRouteRecorder + ], + exports: [ + TabPagingComponent, ShowTitleComponent, AddThisComponent + ] +}) +export class LandingModule { } diff --git a/landingPages/landing-utils/metrics.component.ts b/landingPages/landing-utils/metrics.component.ts new file mode 100644 index 00000000..b4c75833 --- /dev/null +++ b/landingPages/landing-utils/metrics.component.ts @@ -0,0 +1,224 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; +import {Metrics} from '../../utils/entities/metrics'; +import {MetricsService } from '../../services/metrics.service'; +import {ErrorCodes} from '../../utils/properties/openaireProperties'; + +import { Subscription } from 'rxjs/Subscription'; + +@Component({ + selector: 'metrics', + template: ` + + + + + + + + + +
+
Project metrics are derived from aggregating individual research results metrics.
+
+
+ +
{{pageViews}}
+
views in OpenAIRE
+ + + +
+
+
+
+ +
{{metrics.totalViews}} + + ( {{metrics.totalOpenaireViews}} from OpenAIRE ) +
+
views in local repository
+ + + + + +
+
+
+
+ +
{{metrics.totalDownloads}} + + ( {{metrics.totalOpenaireDownloads}} from OpenAIRE ) +
+
downloads in local repository
+ + + + + + +
+
+ +
+ +

The information is available from the following content providers:

+ + + + + + + + + + + + + + + +
FromNumber Of ViewsNumber Of Downloads
+ + {{metrics.infos.get(key).name}} + + + {{metrics.infos.get(key).numOfViews}} + + ( {{metrics.infos.get(key).openaireViews}} from OpenAIRE ) + + + {{metrics.infos.get(key).numOfDownloads}} + + ( {{metrics.infos.get(key).openaireDownloads}} from OpenAIRE ) + +
+ ` + }) + +export class MetricsComponent { + @Output() metricsResults = new EventEmitter(); + @Input() id: string; + @Input() entityType: string; + @Input() entity: string; + //@Input() name: string = ""; + @Input() pageViews: number = 0; + + public metrics: Metrics; + public errorCodes:ErrorCodes; + private sub: Subscription; + + public status: number; + + constructor (private _metricsService: MetricsService) {} + + ngOnInit() { + this.errorCodes = new ErrorCodes(); + this.status = this.errorCodes.LOADING; + this.getMetrics(); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + } + + private getMetrics() { + //if(this.id == undefined || this.id == "") { + // console.log("supplied id in metrics is not acceptable"); + //} + //if(this.type == undefined || this.type == "") { + // console.log("supplied id in metrics is not acceptable"); + //} + + this.sub = this._metricsService.getMetrics(this.id, this.entityType).subscribe( + data => { + this.metrics = data; + this.status = this.errorCodes.DONE; + + this.metricsResults.emit({ + totalViews: this.metrics.totalViews, + totalDownloads: this.metrics.totalDownloads, + pageViews: this.metrics.pageViews + }); + }, + err => { + console.log(err); + if(err.status == '404') { + this.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.status = this.errorCodes.ERROR; + } else { + this.status = this.errorCodes.NOT_AVAILABLE; + } + this.metricsResults.emit({ + totalViews: 0, + totalDownloads: 0 + }); + } + ); + } +} diff --git a/landingPages/landing-utils/metrics.module.ts b/landingPages/landing-utils/metrics.module.ts new file mode 100644 index 00000000..3fb241b4 --- /dev/null +++ b/landingPages/landing-utils/metrics.module.ts @@ -0,0 +1,26 @@ +/* This module contains all common components for all landing pages */ + +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + + import {MetricsComponent} from './metrics.component'; + import { MetricsService } from '../../services/metrics.service'; + + import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, ErrorMessagesModule + ], + declarations: [ + MetricsComponent + ], + providers:[ + MetricsService + ], + exports: [ + MetricsComponent + ] +}) +export class MetricsModule { } diff --git a/landingPages/landing-utils/parsingFunctions.class.ts b/landingPages/landing-utils/parsingFunctions.class.ts new file mode 100644 index 00000000..70b8e0c2 --- /dev/null +++ b/landingPages/landing-utils/parsingFunctions.class.ts @@ -0,0 +1,529 @@ +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + +export class ParsingFunctions { + + constructor () {} + + public ngOnDestroy() {} + + public parseFundingByProjects(fundedByProjects: { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "funding": string, "code": string, + "provenanceAction": string, "inline": boolean + }[], + relation: any, projectsProvenanceVocabulary: any): + { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "funding": string, "code": string, + "provenanceAction": string, "inline": boolean + }[] { + if(fundedByProjects == undefined) { + fundedByProjects = new Array<{"id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "funding": string, "code": string, + "provenanceAction": string, "inline": boolean + }>(); + } + + let fundedByProject: { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "funding": string, "code": string, + "provenanceAction": string, "inline": boolean + } = { "id": "", "acronym": "", "title": "", + "funderShortname": "", "funderName": "", + "funding": "", "code": "", "provenanceAction": "", "inline": false + }; + + if(relation.title != 'unidentified') { + fundedByProject['id'] = relation['to'].content; + fundedByProject['acronym'] = relation.acronym; + fundedByProject['title'] = relation.title; + fundedByProject['code'] = relation.code; + + if(relation.provenanceaction in projectsProvenanceVocabulary) { + fundedByProject['provenanceAction'] = projectsProvenanceVocabulary[relation.provenanceaction]; + } + } else { + fundedByProject['id'] = ""; + fundedByProject['acronym'] = ""; + fundedByProject['title'] = ""; + fundedByProject['code'] = ""; + fundedByProject['provenanceAction'] = ""; + } + + if(relation.hasOwnProperty("funding")) { + let funding: {"funderName": string, "funderShortname": string, "stream": string}; + funding = this.parseFundingTrees(relation.funding); + + if(funding.funderName) { + fundedByProject['funderName'] = funding.funderName; + } + if(funding.funderShortname) { + fundedByProject['funderShortname'] = funding.funderShortname; + } + if(funding.stream) { + fundedByProject['funding'] = funding.stream; + } + } + fundedByProjects.push(fundedByProject); + return fundedByProjects; + } + + // publication & research data : for fundedByProjects | project landing : for funding + public parseFundingTrees(fundingTree: any): {"funderName": string, "funderShortname": string, "stream": string} { + let funding: {"funderName": string, "funderShortname": string, "stream": string} = {"funderName": "", "funderShortname": "", "stream": ""}; + let length = Array.isArray(fundingTree) ? fundingTree.length : 1; + + for(let i=0; i, title: { "name": string, "url": string, "accessMode": string}) { + if( publisher && identifiers != null && identifiers.has('doi')) { + if( hostedBy_collectedFrom == null) { + hostedBy_collectedFrom = new Array<{"downloadName": string, "downloadUrl": string[], "collectedName": string, "collectedId": string, "accessMode": string[], "bestAccessMode": string, "type": string, "year":string}>(); + } + let available: {"downloadName": string, "downloadUrl": string[], "collectedName": string, "collectedId": string, "accessMode": string[], "bestAccessMode": string, "type": string, "year":string}; + available = {"downloadName": "", "downloadUrl": null, "collectedName": "", "collectedId": "", "accessMode": null, "bestAccessMode": null, "type": "", "year": ""}; + + if(journal && journal.journal) { + available.downloadName = publisher + "/ "+journal['journal']; + } else { + available.downloadName = publisher; + } + + let url = OpenaireProperties.getDoiURL()+identifiers.get("doi")[0]; + + available.downloadUrl = new Array(); + available.accessMode = new Array(); + + available.downloadUrl.push(url); + + if(title != undefined && title['url'] == "") { + title['url'] = url; + } + hostedBy_collectedFrom.push(available); + } + return hostedBy_collectedFrom; + } + + // publication & dataset landing : for downloadFrom + parseDownloadFrom(downloadFrom: Map, instance: any, url: string) + { + let key: string = instance['hostedby'].name; + + if(key) { + this.addUrlAndAccessMode(downloadFrom, instance, key, url); + } + } + + // publication & dataset landing : for publishedIn + parsePublishedIn(publishedIn: Map, instance: any, result: any, url: string, counter: number): number { + if(result != null && result.hasOwnProperty("source")) { + let key: string; + if(Array.isArray(result.source)) { + if(counter==result.source.length) { + counter--; + } + key = result['source'][counter]; + } else { + key = result['source']; + } + + if(key) { + this.addUrlAndAccessMode(publishedIn, instance, key, url); + counter++; + } + } + return counter; + } + + // publication & dataset landing : for downloadFrom and publishedIn + addUrlAndAccessMode(mapStructure: Map, instance: any, key: string, url: string) { + if(!mapStructure.has(key)) { + mapStructure.set(key, {"url": null, "accessMode": null, "bestAccessMode": null}); + } + + if(mapStructure.get(key)['url'] == null) { + mapStructure.get(key)['url'] = new Array(); + } + + if(url) { + mapStructure.get(key)['url'].push(url); + } + + if(mapStructure.get(key)['accessMode'] == null) { + mapStructure.get(key)['accessMode'] = new Array(); + } + + if(instance.hasOwnProperty("accessright")) { + if(url) { + mapStructure.get(key)['accessMode'].push(instance['accessright'].classid); + } + + if(this.changeBestAccessMode(mapStructure.get(key)['bestAccessMode'], instance['accessright'])) { + mapStructure.get(key)['bestAccessMode'] = instance['accessright'].classid; + } + } else if(url) { + mapStructure.get(key)['accessMode'].push(""); + } + } + + + parseHostedBy_collectedFrom(hostedBy_collectedFrom: { "downloadName": string, "downloadUrl": string[], + "collectedName": string, "collectedId": string, + "accessMode": string[], "bestAccessMode": string, + "type": string, "year":string }[], + instance: any, data: any, url: string, counter: number, + title: { "name": string, "url": string, "accessMode": string}): number { + let available: {"downloadName": string, "downloadUrl": string[], "collectedName": string, "collectedId": string, "accessMode": string[], "bestAccessMode": string, "type": string, "year":string}; + available = {"downloadName": "", "downloadUrl": null, "collectedName": "", "collectedId": "", "accessMode": null, "bestAccessMode": null, "type": "", "year": ""}; + + if(instance['hostedby'].name && instance['hostedby'].name != "other resources" && instance['hostedby'].name != "Unknown Repository") { + available.downloadName = instance['hostedby'].name; + } else { + if(data != null && data.hasOwnProperty("source")) { + let downloadName: string; + if(Array.isArray(data.source)) { + + if(counter==data.source.length) { + counter--; + } + downloadName = data['source'][counter]; + } else { + downloadName = data['source']; + } + if(downloadName) { + counter++; + available.downloadName = downloadName; + } + } + + } + + if(available.downloadName) { + if(instance.hasOwnProperty("collectedfrom")) { + available.collectedId = instance['collectedfrom'].id; + available.collectedName = instance['collectedfrom'].name; + } + + if(instance.hasOwnProperty("instancetype") && instance['instancetype'].classname) { + available.type = instance['instancetype'].classname; + } + + if(instance.hasOwnProperty("dateofacceptance")) { + var date:string = (instance.dateofacceptance)+""; // transform to string in case it is an integer + available.year = (date && (date).indexOf('-') !== -1)?date.split('-')[0]:date; + } + + available.accessMode = new Array(); + available.downloadUrl = new Array(); + available['downloadUrl'].push(url); + if(instance.hasOwnProperty("accessright")) { + if(url) { + available['accessMode'].push(instance['accessright'].classid); + } + + if(this.changeBestAccessMode(available.bestAccessMode, instance['accessright'])) { + available.bestAccessMode = instance['accessright'].classid; + + if(title != undefined) { + if(this.changeBestAccessMode(title['accessMode'], instance['accessright'])) { + title['accessMode'] = instance['accessright'].classid; + title['url'] = url; + } + } + } + + if(title != undefined) { + if(!title['url']) { + title['url'] = url; + } + } + + } else if(url) { + available['accessMode'].push(""); + } + + hostedBy_collectedFrom.push(available); + } + + return counter; + } + + // publication & dataset landing : for downloadFrom and publishedIn + changeBestAccessMode(currentAccessMode: string, accessMode: any): boolean { + if(!accessMode) { + return false; + } + accessMode = accessMode.classid; + + switch (currentAccessMode) { + case null: + return true; + case "CLOSED": + if( accessMode == "OPEN" || + accessMode == "EMBARGO" || + accessMode == "RESTRICTED") { + return true; + } + return false; + case "RESTRICTED": + if( accessMode == "OPEN" || + accessMode == "EMBARGO") { + return true; + } + return false; + case "EMBARGO": + if(accessMode == "OPEN") { + return true; + } + return false; + } + return false; + } + + // publication & dataset landing : for relatedResearchResults + parseRelatedResearchResults(relatedResearchResults: Map, relation: any, provenanceAction: string) : + Map { + if(relatedResearchResults == undefined) { + relatedResearchResults = new Map(); + } + + if(!relatedResearchResults.has(provenanceAction)) { + relatedResearchResults.set(provenanceAction, + new Array<{ "name": string, "id": string, "date": string, + "trust": number, "class": string }>()); + } + relatedResearchResults.get(provenanceAction).push(this.parseRelatedOrSimilarResearchResult(relation)); + + return relatedResearchResults; + } + + // publication & dataset landing : for similarResearchResults + parseSimilarResearchResults(similarResearchResults: { "name": string, "id": string, "date": string, + "trust": number, "class": string}[], relation: any) : + { "name": string, "id": string, "date": string, "trust": number, "class": string }[] { + if(similarResearchResults == undefined) { + similarResearchResults = new Array<{"name": string, "id": string, "date": string, + "trust": number, "class": string}>(); + } + similarResearchResults.push(this.parseRelatedOrSimilarResearchResult(relation)); + return similarResearchResults; + } + + // publication & dataset landing : for relatedResearchResults and similarResearchResults + parseRelatedOrSimilarResearchResult(relation: any): {"name": string, "id": string, "date": string, "trust": number, "class": string} { + let researchResult: {"name": string, "id": string, "date": string, "trust": number, "class": string} + = {"name": "", "id": "", "date": "", "trust": null, "class": ""} + + if(relation['resulttype'].classname == "publication") { + researchResult['class'] = "publication"; + } else if(relation['resulttype'].classname == "dataset") { + researchResult['class'] = "dataset"; + } else { + researchResult['class'] = "software"; + } + + researchResult['id'] = relation['to'].content; + let titleName = Array.isArray(relation['title']) ? relation['title'][0].content : relation['title'].content; + researchResult['name'] = titleName; + var date:string = ((Array.isArray(relation.dateofacceptance))?(relation.dateofacceptance[0]):(relation.dateofacceptance))+""; // transform to string in case it is an integer + researchResult['date'] = (date && (date).indexOf('-') !== -1)?date.split('-')[0]:date; + //researchResult['date'] = relation.dateofacceptance.substring(0,4);; + researchResult['trust'] = Math.round(relation.trust*100); + return researchResult; + } + + // publication & dataset landing : for identifiers + parseIdentifiers(pid: any): Map { + let identifiers = new Map(); + + if(pid.hasOwnProperty("classname") && pid['classname'] != "") { + if(pid.classname == "doi" || pid.classname == "pmc" || pid.classname == "handle") { + if(!identifiers.has(pid.classname)) { + identifiers.set(pid.classname, new Array()); + } + + identifiers.get(pid.classname).push(pid.content); + } + } else { + for(let i=0; i()); + } + identifiers.get(pid[i].classname).push(pid[i].content); + } + } + } + return identifiers; + } + + // publication & dataset landing : for subjects and otherSubjects and classifiedSubjects + parseAllSubjects(_subjects: any): [string[], Map, Map] { + let subjects: string[]; + let otherSubjects: Map; + let classifiedSubjects: Map; + + let subject; + let length = Array.isArray(_subjects) ? _subjects.length : 1; + + for(let i=0; i(); + } + + if(!classifiedSubjects.has(subject.classname)) { + classifiedSubjects.set(subject.classname, new Array()); + } + + classifiedSubjects.get(subject.classname).push(subject.content); + } else { + if(subject.classid == "keyword") { + if(subjects == undefined) { + subjects = new Array(); + } + + subjects.push(subject.content); + } else { + if(otherSubjects == undefined) { + otherSubjects = new Map(); + } + + if(!otherSubjects.has(subject.classname)) { + otherSubjects.set(subject.classname, new Array()); + } + otherSubjects.get(subject.classname).push(subject.content); + } + } + } + } + return [subjects, otherSubjects, classifiedSubjects]; + } + + parseContexts(_contexts: any): {"labelContext": string, "labelCategory": string, + "labelConcept": string, inline:boolean}[] { + let contexts = new Array<{"labelContext": string, "labelCategory": string, + "labelConcept": string, inline:boolean}>(); + + let position = 0; + let labels = ""; + let context; + let length = Array.isArray(_contexts) ? _contexts.length : 1; + for(let i=0; i, instance: any) { + if(instance.hasOwnProperty("instancetype") && instance['instancetype'].classname) { + if(!uniqueTypes.has(instance['instancetype'].classname)) { + types.push(instance['instancetype'].classname); + uniqueTypes.add(instance['instancetype'].classname); + } + } + } +} diff --git a/landingPages/landing-utils/publishedIn.component.ts b/landingPages/landing-utils/publishedIn.component.ts new file mode 100644 index 00000000..7a4f47be --- /dev/null +++ b/landingPages/landing-utils/publishedIn.component.ts @@ -0,0 +1,71 @@ +import {Component, Input, ElementRef} from '@angular/core'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'publishedIn', + template: ` +
+
Published in
+
+
+ + + {{key}} + + + [{{i+1}}] + + + + + {{key}} + + + {{key}} + + +
+
+
+ + View less + +
+
...
+
+ + View more + +
+
+ ` + }) + +export class PublishedInComponent { + //key is name + @Input() publishedIn: Map; + + public showAll: boolean = false; + + constructor (private element: ElementRef) {} + + ngOnInit() {} + + public scroll() { + console.info("scroll into view"); + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + } + public getKeys( map) { + return Array.from(map.keys()); + } +} diff --git a/landingPages/landing-utils/resultLanding.module.ts b/landingPages/landing-utils/resultLanding.module.ts new file mode 100644 index 00000000..5233be99 --- /dev/null +++ b/landingPages/landing-utils/resultLanding.module.ts @@ -0,0 +1,31 @@ +/* This module contains all common components for Publication & Daasets Landing Pages */ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; +import {PagingModule} from '../../utils/paging.module'; + +import {ShowAuthorsComponent} from './showAuthors.component'; +import {ShowIdentifiersComponent} from './showIdentifiers.component'; +import {ShowSubjectsComponent} from './showSubjects.component'; +import {FundedByComponent} from './fundedBy.component'; +import {PublishedInComponent} from './publishedIn.component'; +import {AvailableOnComponent} from './availableOn.component'; +import {TabTableComponent} from './tabTable.component'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, PagingModule + ], + declarations: [ + ShowAuthorsComponent,ShowIdentifiersComponent,ShowSubjectsComponent, + FundedByComponent,PublishedInComponent,AvailableOnComponent,TabTableComponent + ], + providers:[ + ], + exports: [ + ShowAuthorsComponent,ShowIdentifiersComponent,ShowSubjectsComponent, + FundedByComponent,PublishedInComponent,AvailableOnComponent,TabTableComponent + ] +}) +export class ResultLandingModule { } diff --git a/landingPages/landing-utils/searchingProjectsInTab.component.ts b/landingPages/landing-utils/searchingProjectsInTab.component.ts new file mode 100644 index 00000000..c96d23ba --- /dev/null +++ b/landingPages/landing-utils/searchingProjectsInTab.component.ts @@ -0,0 +1,122 @@ +import {Component, Input} from '@angular/core'; +import {ActivatedRoute} from '@angular/router'; + +import { FetchProjects } from '../../utils/fetchEntitiesClasses/fetchProjects.class'; +import { SearchProjectsService } from '../../services/searchProjects.service'; + +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {StringUtils} from '../../utils/string-utils.class'; +import {RouterHelper} from '../../utils/routerHelper.class'; + +@Component({ + selector: 'searchingProjectsTab', + template: ` + + + + +
+ +
+
+
+ +
+
+
    +
  • + + + + {{value.name}} ({{value.number}}) + +
  • + +
  • Filtered {{fetchProjects.searchUtils.totalResults}} results of {{fetchProjects.searchUtils.totalResultsNoFilters}} total results
  • +
  • +
+ + + +
+
+ ` +}) + +export class SearchingProjectsTabComponent { + @Input() fetchProjects : FetchProjects; + @Input() organizationId:string = ""; + public page :number = 1; + public size :number = 10; + public linkToSearchProjects: string; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + private filterQuery:string = ""; + + constructor (private route: ActivatedRoute, + private _searchProjectsService: SearchProjectsService) { + } + + + ngOnInit() { + + if(this.organizationId) { + this.linkToSearchProjects = OpenaireProperties.getLinkToAdvancedSearchProjects();//+"?organization="+this.organizationId+"or=and";; + if(this.fetchProjects.searchUtils.totalResults > 0) { + this.search(false,""); + } + } + } + + + private search(refine:boolean, filterQuery:string){ + var refineFields:string [] = ["funder"]; + this.fetchProjects.getResultsForOrganizations(this.organizationId, filterQuery, this.page, this.size,(refine)?refineFields:[]); + } + + public pageChange($event) { + this.page=$event.value; + this.search(false, this.filterQuery); + } + + public filterChange($event) { + console.log("Filter Changed"); + this.updateFilters(); + //this.search(true, this.filterQuery); + this.search(false, this.filterQuery); + } + + private updateFilters (){ + this.filterQuery = ""; + for (let filter of this.fetchProjects.filters){ + var filterLimits=""; + for (let value of filter.values){ + if(value.selected == true){ + //filterLimits+=((filterLimits.length == 0)?'':',') +'"'+ StringUtils.URIEncode(value.id)+'"'; + filterLimits+=((filterLimits.length == 0)?'':' or ')+filter.filterId+' exact '; + filterLimits+='"'+ StringUtils.URIEncode(value.id)+'"'; + } + } + if(filterLimits.length > 0){ + //this.filterQuery+=' and '+filter.filterId + ' exact '+ filterLimits + ' '; + this.filterQuery+=' and ( ' + filterLimits + ' ) '; + } + + } + console.log("Filter Changed"+this.filterQuery); + + } +} diff --git a/landingPages/landing-utils/searchingProjectsInTab.module.ts b/landingPages/landing-utils/searchingProjectsInTab.module.ts new file mode 100644 index 00000000..e3d7a061 --- /dev/null +++ b/landingPages/landing-utils/searchingProjectsInTab.module.ts @@ -0,0 +1,31 @@ +/* This module contains all common components for all landing pages */ + +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import { ProjectsServiceModule} from '../../services/projectsService.module'; +import { TabResultModule } from '../../searchPages/searchUtils/tabResult.module'; +import { SearchingProjectsTabComponent} from './searchingProjectsInTab.component'; + +import {PagingModule } from '../../utils/paging.module'; +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +@NgModule({ + imports: [ + RouterModule, CommonModule, FormsModule, + ProjectsServiceModule, TabResultModule, + PagingModule, ErrorMessagesModule + ], + declarations: [ + SearchingProjectsTabComponent + ], + providers:[ + ], + exports: [ + + SearchingProjectsTabComponent + ] +}) +export class SearchingProjectsTabModule { } diff --git a/landingPages/landing-utils/showAuthors.component.ts b/landingPages/landing-utils/showAuthors.component.ts new file mode 100644 index 00000000..517d9372 --- /dev/null +++ b/landingPages/landing-utils/showAuthors.component.ts @@ -0,0 +1,65 @@ +import {Component, Input, ElementRef} from '@angular/core'; +import {RouterHelper} from '../../utils/routerHelper.class'; + +@Component({ + selector: 'showAuthors', + template: ` + + + + + {{author}} + ; + + ... + + + + {{author}} + ; + + + + + view all {{authors.length}} authors + + + + View less authors + + + + ` + + }) + +export class ShowAuthorsComponent { + @Input() authors: { [key: string]: string }[]; + @Input() searchPage:string ="publications" + + public showAll: boolean = false; + public routerHelper:RouterHelper = new RouterHelper(); + + constructor (private element: ElementRef) { + } + + ngOnInit() { + } + + public quote(params: string):string { + return '"'+params+'"'; + } + + public scroll() { + console.info("scroll into view"); + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + } +} diff --git a/landingPages/landing-utils/showIdentifiers.component.ts b/landingPages/landing-utils/showIdentifiers.component.ts new file mode 100644 index 00000000..1092d55c --- /dev/null +++ b/landingPages/landing-utils/showIdentifiers.component.ts @@ -0,0 +1,94 @@ +import {Component, Input, ElementRef} from '@angular/core'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'showIdentifiers', + template: ` + + + View less identifiers + + + + + + + {{key}}: {{item}}{{key}}: {{item}}{{key}}: {{item}}{{", "}} + ... + + + + + + + view all {{countIdentifiers()}} identifiers + + + + View less identifiers + + + + ` + }) + +export class ShowIdentifiersComponent { + @Input() identifiers: Map; + public doiURL: string; + public pmcURL: string; + public handleURL: string; + public showAll: boolean = false; + public sizeOfIdentifiers: number = -1; + public sizeOfPreviousIdentifiers: number = -1; + public pageSize: number = 10; + + constructor (private element: ElementRef) { + this.doiURL = OpenaireProperties.getDoiURL(); + this.pmcURL = OpenaireProperties.getPmcURL(); + this.handleURL = OpenaireProperties.getHandleURL(); + } + + ngOnInit() {} + + public countIdentifiers(): number { + if(this.sizeOfIdentifiers < 0) { + let num: number = 0; + if(this.identifiers != undefined) { + this.identifiers.forEach(function (value, key, map) { + num += value.length; + }); + } + this.sizeOfIdentifiers = num; + } + return this.sizeOfIdentifiers; + } + + public countSizeOfPreviousIdentifiers(index: number): number { + let num: number = 0; + let i: number = 0; + if(this.identifiers != undefined) { + this.identifiers.forEach(function (value, key, map) { + if(i < index) { + num += value.length; + } + i++; + }); + } + this.sizeOfPreviousIdentifiers= num; + return num; + } + + public scroll() { + console.info("scroll into view"); + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + } + public getKeys( map) { + return Array.from(map.keys()); + } +} diff --git a/landingPages/landing-utils/showSubjects.component.ts b/landingPages/landing-utils/showSubjects.component.ts new file mode 100644 index 00000000..e3f4faa5 --- /dev/null +++ b/landingPages/landing-utils/showSubjects.component.ts @@ -0,0 +1,57 @@ +import {Component, Input} from '@angular/core'; + +@Component({ + selector: 'showSubjects', + template: ` +
+ +
+ Subject: + + {{subjects.join(" | ")}} +
    +
  • +
    + {{key}}: {{otherSubjects.get(key).join(" | ")}} +
    +
  • + +
+
+ +
+
+
+ Classified by OpenAIRE into +
+ {{key}}: {{classifiedSubjects.get(key).join(" | ")}} +
+
+
+
+
+ ` + + }) + +export class ShowSubjectsComponent { + @Input() subjects: string[]; + @Input() otherSubjects: Map; + @Input() classifiedSubjects: Map; + // private showClassifiedSbj: boolean = false; + + constructor () { + } + + ngOnInit() { + } + public getKeys( map) { + return Array.from(map.keys()); + } +} diff --git a/landingPages/landing-utils/showTitle.component.ts b/landingPages/landing-utils/showTitle.component.ts new file mode 100644 index 00000000..a458aae9 --- /dev/null +++ b/landingPages/landing-utils/showTitle.component.ts @@ -0,0 +1,66 @@ +import {Component, Input} from '@angular/core'; +import {ActivatedRoute} from '@angular/router'; + +@Component({ + selector: 'showTitle', + template: ` +

+ + + + + + + [no title available] + + + + + + + [no title available] + +

+ + ` + + }) + +export class ShowTitleComponent { + @Input() title: { [key: string]: string }; + @Input() iconClass:string; + + sub: any; + + constructor (private route: ActivatedRoute) {} + + ngOnInit() { + this.sub = this.route.queryParams.subscribe( + params => { + console.info("onInit showTitle"); + + if(this.title['accessMode'] == undefined) { + this.title['accessMode'] = ""; + } + } + ); + } + + ngOnDestroy() { + console.info("onDestroy showTitle"); + this.sub.unsubscribe(); + } +} diff --git a/landingPages/landing-utils/tabPaging.component.ts b/landingPages/landing-utils/tabPaging.component.ts new file mode 100644 index 00000000..f0671764 --- /dev/null +++ b/landingPages/landing-utils/tabPaging.component.ts @@ -0,0 +1,24 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; + +@Component({ + selector: 'tabPaging', + template: ` + + ` + }) + +export class TabPagingComponent { + @Input() showAll: boolean; + @Input() length: number; + @Output() changeShowAll: EventEmitter = new EventEmitter(); + + constructor () { + } + + ngOnInit() { + } +} diff --git a/landingPages/landing-utils/tabTable.component.ts b/landingPages/landing-utils/tabTable.component.ts new file mode 100644 index 00000000..83e51e77 --- /dev/null +++ b/landingPages/landing-utils/tabTable.component.ts @@ -0,0 +1,99 @@ +import {Component, Input} from '@angular/core'; +import {RouterHelper} from '../../utils/routerHelper.class'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +//import {PagingModule} from '../utils/paging.module'; + +@Component({ + selector: 'tabTable', + template: ` +
+ {{info.length}} research results, page {{page}} of {{totalPages(info.length)}} + +
+ + + + + + + + + +
+ + (Publication) + (Dataset) + (Software) + + + + + {{item['name']}} + + + + {{item['name']}} + + + + + + {{item['name']}} + + +

{{item['name']}}

+ + ({{item['date']}}) + +
+
+
{{item['trust']}}%
+ +
+
+

No trust available

+
+
+ ` + + }) + +export class TabTableComponent { + @Input() info: { "name": string, "url": string, "date": string, "trust": number}[];//Map; + + public routerHelper:RouterHelper = new RouterHelper(); + public searchLinkToPublication: string; + public searchLinkToDataset: string; + + public page: number = 1; + public pageSize: number = 10; + + constructor () { + } + + ngOnInit() { + this.searchLinkToPublication = OpenaireProperties.getsearchLinkToPublication(); + this.searchLinkToDataset = OpenaireProperties.getsearchLinkToDataset(); + } + + totalPages(totalResults: number): number { + let totalPages:any = totalResults/this.pageSize; + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, this.pageSize) + 1); + } + return totalPages; + } + + updatePage($event) { + this.page = $event.value; + } +} diff --git a/landingPages/organization/organization-routing.module.ts b/landingPages/organization/organization-routing.module.ts new file mode 100644 index 00000000..52d44be3 --- /dev/null +++ b/landingPages/organization/organization-routing.module.ts @@ -0,0 +1,18 @@ +// import { NgModule } from '@angular/core'; +// import { RouterModule } from '@angular/router'; +// +// import { OrganizationComponent } from './organization.component'; +// import {FreeGuard} from'../../login/freeGuard.guard'; +// import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +// import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; +// +// @NgModule({ +// imports: [ +// RouterModule.forChild([ +// { path: '', component: OrganizationComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { +// redirect: '/error' +// },canDeactivate: [PreviousRouteRecorder] } +// ]) +// ] +// }) +// export class OrganizationRoutingModule { } diff --git a/landingPages/organization/organization.component.html b/landingPages/organization/organization.component.html new file mode 100644 index 00000000..83ebdb03 --- /dev/null +++ b/landingPages/organization/organization.component.html @@ -0,0 +1,196 @@ + diff --git a/landingPages/organization/organization.component.ts b/landingPages/organization/organization.component.ts new file mode 100644 index 00000000..1e02b02d --- /dev/null +++ b/landingPages/organization/organization.component.ts @@ -0,0 +1,489 @@ +import {Component, ViewChild, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {Subject} from 'rxjs/Subject'; +import {ActivatedRoute, Router} from '@angular/router'; + +import {OrganizationService} from '../../services/organization.service'; +import {OrganizationInfo} from '../../utils/entities/organizationInfo'; +import {ReportsService} from '../../services/reports.service'; +import {FetchPublications} from '../../utils/fetchEntitiesClasses/fetchPublications.class'; +import {FetchProjects} from '../../utils/fetchEntitiesClasses/fetchProjects.class'; +import {FetchDataproviders} from '../../utils/fetchEntitiesClasses/fetchDataproviders.class'; +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchProjectsService} from '../../services/searchProjects.service'; +import { Meta} from '../../../angular2-meta'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchingProjectsTabComponent} from '../landing-utils/searchingProjectsInTab.component'; +import {RouterHelper} from '../../utils/routerHelper.class'; + +import {ModalLoading} from '../../utils/modal/loading.component'; +import {AlertModal} from '../../utils/modal/alert'; +import {PiwikService} from '../../utils/piwik/piwik.service'; +import {StringUtils} from '../../utils/string-utils.class'; + +@Component({ + selector: 'organization', + templateUrl: 'organization.component.html', +}) + +export class OrganizationComponent { + public organizationInfo: OrganizationInfo; + public organizationId: string; + + // Message variables + public warningMessage = ""; + public errorMessage = ""; + public showLoading: boolean = true; + + // CSV variables + public downloadURLAPI: string; + public csvProjectParamsHead: string; + public csvPublicationParamsHead: string; + public csvParamsTail: string; + + // Active tab variable for responsiveness + public activeTab: string = "Publications"; + + // Variables for publications, projects, dataproviders tabs + public fetchPublications: FetchPublications; + public linkToSearchPublications: string = ""; + public fetchProjects: FetchProjects; + public fetchDataproviders : FetchDataproviders; + public linkToSearchDataproviders:string = ""; + //public projectFunders:string[] = []; + + // Variables for projects query (query results only if projects tab is clicked) + public projectsClicked: boolean = false; + @ViewChild (SearchingProjectsTabComponent) searchingProjectsTabComponent : SearchingProjectsTabComponent ; + + @ViewChild (ModalLoading) loading : ModalLoading ; + // Alert box when CSV: Project Publications for a funder is requested + @ViewChild('AlertModalApplyAll') alertApplyAll; + // Alert box when something is wrong with CSV requests + @ViewChild('AlertModalCsvError') alertCsvError; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + //private projectsNum: number = 0; + //private fundersSet: Set; + //private emptyFundersSet: boolean = true; + + // Request results for content providers only the one time (first time tab is clicked) + private reloadDataproviders: boolean = true; + + // Helper variables to specify funder in downloadPublicationsFile function + private funder: string; + private funderId: string; + private funderCountPublications: number; + sub: any; + infoSub: any; + piwiksub: any; + downloadFileSub: any; + downloadFilePiwikSub: any; + countProjectsSub: any; + countPublSub: any; + downloadProjectPublSub: any; + + //private ngUnsubscribe: Subject = new Subject(); + + constructor (private element: ElementRef, + private _organizationService: OrganizationService, + private _piwikService:PiwikService, + private route: ActivatedRoute, + private _searchDataprovidersService: SearchDataprovidersService, + private _reportsService: ReportsService, + private _searchPublicationsService: SearchPublicationsService, + private _searchProjectsService: SearchProjectsService, private _meta: Meta, + private _router: Router) { + + this.fetchPublications = new FetchPublications(this._searchPublicationsService); + this.fetchProjects = new FetchProjects(this._searchProjectsService); + this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService); + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + console.info('organization init'); + this.sub = this.route.queryParams.subscribe(params => { + this.organizationInfo=null; + this.updateTitle("Organization"); + this.updateDescription("Organization, country, projects, search, repositories, open access"); + this.projectsClicked = false; + + this.organizationId = params['organizationId']; + console.info("Id is :"+this.organizationId); + + if(this.organizationId){ + this.getOrganizationInfo(); + }else{ + this.showLoading = false; + this.warningMessage="No valid organization id"; + } + + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + + this.csvParamsTail = '" and relorganizationid exact "'+this.organizationId+'" ))'; + + }); + + this.downloadURLAPI = OpenaireProperties.getCsvAPIURL(); + this.csvProjectParamsHead = 'format=csv&type=projects&page=0&query=( (oaftype exact project)and (funder exact "'; + //this.csvPublicationParamsHead = 'format=csv-special&type=publications&page=0&query=((((oaftype exact result) and (resulttypeid exact publication)) and (funderid exact '; + } + + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.infoSub) { + this.infoSub.unsubscribe(); + } + if(this.downloadFileSub) { + this.downloadFileSub.unsubscribe(); + } + if(this.downloadFilePiwikSub) { + this.downloadFilePiwikSub.unsubscribe(); + } + if(this.countProjectsSub) { + this.countProjectsSub.unsubscribe(); + } + if(this.countPublSub) { + this.countPublSub.unsubscribe(); + } + if(this.downloadProjectPublSub) { + this.downloadProjectPublSub.unsubscribe(); + } + + /* + this.ngUnsubscribe.next(); + this.ngUnsubscribe.complete(); + */ + } + + private getOrganizationInfo () { + + this.warningMessage = ''; + this.errorMessage="" + this.showLoading = true; + + this.infoSub = this._organizationService.getOrganizationInfo(this.organizationId).subscribe( + data => { + if(data == null) { + this.showLoading = false; + this.errorMessage = 'No organization found'; + } else { + this.organizationInfo = data; + this.updateTitle(this.organizationInfo.title.name); + this.updateDescription("Organization, country, projects, search, repositories, open access"+this.organizationInfo.title.name); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.organizationInfo.title.name).subscribe(); + } + var refineFields:string [] = ["funder"]; + + this.searchPublications(); + + this.fetchProjects.getResultsForOrganizations(this.organizationId, "", 1, 0,refineFields); + + this.fetchDataproviders.getNumForEntity("organization", this.organizationId); + + this.showLoading = false; + + /*let projectsNum = 0; + + if(this.organizationInfo.projects != undefined) { + this.fundersSet = new Set(); + this.organizationInfo.projects.forEach(function (value, key, map) { + projectsNum += value.length; + this.fundersSet.add(key); + }.bind(this)); + } + + this.projectsNum = projectsNum;*/ + } + }, + err => { + console.log(err) + + this.errorMessage = 'No organization found'; + this.showLoading = false; + } + ); + } +/* + private getMetrics() { + console.info("getOrganizationMetrics: component"); + this._organizationService.getMetrics(this.organizationId).subscribe( + data => { + this.metrics = data; + }, + err => { + console.log(err); + } + ); + } +*/ +/* + private handleClick(funder: string) { + if(this.emptyFundersSet) { + this.fundersSet.clear(); + this.emptyFundersSet = false; + } + + if(this.fundersSet.has(funder)) { + this.fundersSet.delete(funder); + + if(this.fundersSet.size == 0) { + this.organizationInfo.projects.forEach(function (value, key, map) { + this.fundersSet.add(key); + }.bind(this)); + this.emptyFundersSet = true; + } + console.info(funder+" funder deleted"); + } else { + this.fundersSet.add(funder); + console.info(funder+" funder added"); + } + } +*/ + //private getProjectsData(key: string): any { + //return this.projectsData; + //} + + private searchPublications() { + this.fetchPublications.getResultsForEntity("organization", this.organizationId, 1, 10); + this.linkToSearchPublications = OpenaireProperties.getLinkToAdvancedSearchPublications();// + "?project=" + this.projectId+"&pr=and"; + if(this.fetchPublications.searchUtils.totalResults > 0) { + //this.activeTab = "Publications"; + } else { + //this.projectsClicked = true; + } + } + + private searchDataproviders() { + this.fetchDataproviders.getResultsForEntity("organization", this.organizationId, 1, 10); + this.linkToSearchDataproviders = OpenaireProperties.getLinkToAdvancedSearchDataProviders(); + + if(this.fetchDataproviders.searchUtils.totalResults > 0) { + this.reloadDataproviders = false; + //this.activeTab = "Content Providers"; + } else { + + } + } + + public searchDataprovidersInit() { + if(this.reloadDataproviders && this.fetchDataproviders.searchUtils.totalResults > 0) { + this.searchDataproviders(); + } + } + + public downloadFile(url:string){ + console.log("Downloading file: "+ url); + + this.openLoading(); + this.setMessageLoading("Downloading CSV file"); + + this.downloadFileSub = this._reportsService.downloadCSVFile(url).subscribe( + data => { + this.closeLoading(); + window.open(window.URL.createObjectURL(data)); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.downloadFilePiwikSub = this._piwikService.trackDownload(url).subscribe(); + } + }, + err => { + console.log("Error downloading the file."); + this.closeLoading(); + this.confirmOpenCsvError(); + }, + () => console.log('Completed file download.')); + } + + private downloadPublicationsFile(funder: string, funderId:string, count:number){ + console.log("Downloading publications file"); + + this.openLoading(); + this.setMessageLoading("Downloading CSV file"); + + let response: string[] = []; + let totalResponse: string = ""; + let projects = []; + let counter: number = count; + let title: boolean = false; + + this.countProjectsSub = this._searchProjectsService.getProjectsForOrganizations(this.organizationId,' and (funder exact "'+ funderId + '" ) ',1,count,[]).subscribe( + data => + { + projects = data[1]; + for(let index=0; index < projects.length; index++) { + this.countPublSub = this._searchPublicationsService.numOfEntityPublications(projects[index].id, "project").subscribe( + data => + { + // let index: number = this.organizationInfo.projects.get(funder).indexOf(project); + + let url: string; + if(index == 0 || !title) { + url = this.downloadURLAPI+"projects/"+projects[index].id+"/publications?format=csv-special&size="+data; + } else { + url = this.downloadURLAPI+"projects/"+projects[index].id+"/publications?format=csv-special-notitle&size="+data; + } + + if(data == 0) { // if no publications for this project + counter--; + response[index] = ""; + if(counter == 0) { + for(let i=0; i + { + counter--; + response[index] = data; + + if(counter == 0) { + for(let i=0; i { + console.log("Error downloading the file."); + this.closeLoading(); + this.confirmOpenCsvError(); + }, + () => console.log('Completed file download.') + ); + } + }, + err => console.log("Error getting number of publications for project.")); + }//); + + }, + err => { + console.log("Error getting projects project."); + this.closeLoading(); + this.confirmOpenCsvError(); + } + ); + + // let counter: number = this.organizationInfo.projects.get(funder).length; + // + // for(let project of this.organizationInfo.projects.get(funder)) { + // this._searchPublicationsService.numOfEntityPublications(project.id, "projects/").subscribe( + // data => + // { + // let index: number = this.organizationInfo.projects.get(funder).indexOf(project); + // + // let url: string; + // if(index == 0) { + // url = this.downloadURLAPI+"projects/"+project.id+"/publications?format=csv-special&size="+data; + // } else { + // url = this.downloadURLAPI+"projects/"+project.id+"/publications?format=csv-special-notitle&size="+data; + // } + // + // this._reportsService.getCSVResponse(url).subscribe( + // data => + // { + // counter--; + // + // response[index] = data; + // + // if(counter == 0) { + // for(let i=0; i console.log("Error downloading the file."), + // () => console.log('Completed file download.')); + // }, + // error => console.log("Error getting number of publications for project.")); + // }//); + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + private openLoading(){ + if(this.loading){ + this.loading.open(); + } + } + private closeLoading(){ + if(this.loading){ + this.loading.close(); + } + } + private setMessageLoading(message: string){ + if(this.loading){ + this.loading.message = message; + } + } + + public confirmOpenApplyAll(funder: string, funderId:string, funderCountPublications:number){ + this.alertApplyAll.cancelButton = true; + this.alertApplyAll.okButton = true; + this.alertApplyAll.alertTitle = "CSV FILE"; + this.alertApplyAll.message = "Do you wish to download a CSV file? Note that this process may take a while."; + this.alertApplyAll.okButtonText = "Yes"; + this.alertApplyAll.cancelButtonText = "No"; + this.alertApplyAll.open(); + + this.funder = funder; + this.funderId = funderId; + this.funderCountPublications = funderCountPublications; + } + public confirmCloseApplyAll(data){ + this.downloadPublicationsFile(this.funder, this.funderId, this.funderCountPublications); + } + + public confirmOpenCsvError(){ + this.alertCsvError.cancelButton = false; + this.alertCsvError.okButton = true; + this.alertCsvError.alertTitle = "ERROR DOWNLOADING CSV FILE"; + this.alertCsvError.message = "There was an error in csv downloading. Please try again later."; + this.alertCsvError.okButtonText = "OK"; + this.alertCsvError.open(); + } + + encodeURI(input: string): string { + return StringUtils.URIEncode(input); + } +} diff --git a/landingPages/organization/organization.module.ts b/landingPages/organization/organization.module.ts new file mode 100644 index 00000000..8c17083e --- /dev/null +++ b/landingPages/organization/organization.module.ts @@ -0,0 +1,51 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {LoadingModalModule} from '../../utils/modal/loadingModal.module'; +import {AlertModalModule} from '../../utils/modal/alertModal.module'; +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +import { OrganizationServiceModule} from '../../services/organizationService.module'; +// import { ProjectsServiceModule} from '../../services/projectsService.module'; +import { OrganizationComponent } from './organization.component'; +// import { OrganizationRoutingModule } from './organization-routing.module'; + +import { LandingModule } from '../landing-utils/landing.module'; +import {TabResultModule } from '../../searchPages/searchUtils/tabResult.module'; +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {ReportsServiceModule} from '../../services/reportsService.module'; +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {ProjectsServiceModule} from '../../services/projectsService.module'; + +import { SearchingProjectsTabModule} from '../landing-utils/searchingProjectsInTab.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, + LoadingModalModule, AlertModalModule, ErrorMessagesModule, + LandingModule, + TabResultModule, + DataProvidersServiceModule, + ReportsServiceModule, + OrganizationServiceModule, + SearchingProjectsTabModule, + OrganizationServiceModule, + PublicationsServiceModule, + ProjectsServiceModule + + ], + declarations: [ + OrganizationComponent, + ], + providers:[ + FreeGuard, IsRouteEnabled + ], + exports: [ + OrganizationComponent + ] +}) +export class OrganizationModule { } diff --git a/landingPages/project/project-routing.module.ts b/landingPages/project/project-routing.module.ts new file mode 100644 index 00000000..2eff3b40 --- /dev/null +++ b/landingPages/project/project-routing.module.ts @@ -0,0 +1,18 @@ +// import { NgModule } from '@angular/core'; +// import { RouterModule } from '@angular/router'; +// +// import { ProjectComponent } from './project.component'; +// import {FreeGuard} from'../../login/freeGuard.guard'; +// import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; +// import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; +// +// @NgModule({ +// imports: [ +// RouterModule.forChild([ +// { path: '', component: ProjectComponent, canActivate: [FreeGuard, IsRouteEnabled], data: { +// redirect: '/error' +// },canDeactivate: [PreviousRouteRecorder] } +// ]) +// ] +// }) +// export class ProjectRoutingModule { } diff --git a/landingPages/project/project.component.html b/landingPages/project/project.component.html new file mode 100644 index 00000000..43a4b467 --- /dev/null +++ b/landingPages/project/project.component.html @@ -0,0 +1,400 @@ +
+
+
+ +
+ + + + +
+
+ +

+ + + {{projectName}} + ({{projectInfo.contractNum}}) +

+
{{projectInfo.title}} ({{projectInfo.contractNum}})
+
+ Project + {{projectInfo.funder}} + Open Access mandate + Special Clause 39 +
+ + + + + + + + + + + +
+ + + + + +
+ + + + +
+ +
+

Research Results

+ +

Access Mode of Research Results

+ +

By Datasource of Research Results

+ +
+
+
+
+ + + + + + + + + +
+ +
+
+ +
+
+
+ Share - Bookmark +
+
+
+ Application Box +
+ + +
+ +
+
+
+ + +
+
+
+
diff --git a/landingPages/project/project.component.ts b/landingPages/project/project.component.ts new file mode 100644 index 00000000..3e8f32d3 --- /dev/null +++ b/landingPages/project/project.component.ts @@ -0,0 +1,374 @@ +import {Component, ViewChild, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Params, Router} from '@angular/router'; +import {ProjectService} from './project.service'; +import {ProjectInfo} from '../../utils/entities/projectInfo'; +import {RouterHelper} from '../../utils/routerHelper.class'; + +import { FetchPublications } from '../../utils/fetchEntitiesClasses/fetchPublications.class'; +import { SearchPublicationsService } from '../../services/searchPublications.service'; +import { FetchDatasets } from '../../utils/fetchEntitiesClasses/fetchDatasets.class'; +import { SearchDatasetsService } from '../../services/searchDatasets.service'; +import { FetchSoftware } from '../../utils/fetchEntitiesClasses/fetchSoftware.class'; +import { SearchSoftwareService } from '../../services/searchSoftware.service'; + +import {ModalLoading} from '../../utils/modal/loading.component'; + +import {ReportsService} from '../../services/reports.service'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import { Meta} from '../../../angular2-meta'; + +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'project', + templateUrl: 'project.component.html', + }) +export class ProjectComponent{ + public projectInfo: ProjectInfo; + public projectId : string ; + public projectName: string; + + // Metrics tab variables + public metricsClicked: boolean; + public viewsFrameUrl: string; + public downloadsFrameUrl: string; + private totalViews: number; + private totalDownloads: number; + private pageViews: number; + + // Statistics tab variables + public statsClicked: boolean; + public chartScientificResultsUrl: string; + public chartAccessModeUrl: string; + public chartDatasourcesUrl: string; + + // HTML variables in APP BOX + public publications_dynamic: string; + public datasets_dynamic: string; + public software_dynamic: string; + + public project ; + + // CSV variables + public downloadURLAPI: string; + public csvParams: string; + public csvParamsDatasets: string; + public csvParamsSoftware: string; + + // Message variables + public warningMessage = ""; + public errorMessage = ""; + public showLoading: boolean = true; + + // Active tab variable for responsiveness + public activeTab: string = "Publications"; + + // Request results for research data and software only the one time (first time tab is clicked) + private reloadDatasets: boolean = true; + private reloadSoftware: boolean = true; + + // Variables for publications, research data, software tabs + public fetchPublications : FetchPublications; + public linkToSearchPublications = ""; + public fetchDatasets : FetchDatasets; + public linkToSearchDatasets = ""; + public fetchSoftware: FetchSoftware; + public linkToSearchSoftware = ""; + + public routerHelper:RouterHelper = new RouterHelper(); + public errorCodes:ErrorCodes = new ErrorCodes(); + + @ViewChild (ModalLoading) loading : ModalLoading ; + // Alert box when something is wrong with CSV requests + @ViewChild('AlertModalCsvError') alertCsvError; + + sub: any; piwiksub: any; infoSub: any; downloadFilePiwikSub: any; + + constructor ( private element: ElementRef, + private _projectService: ProjectService, + private _piwikService:PiwikService, + private route: ActivatedRoute, + private _searchPublicationsService: SearchPublicationsService, + private _searchDatasetsService: SearchDatasetsService, + private _searchSoftwareService: SearchSoftwareService, + private _reportsService: ReportsService, private _meta: Meta, + private _router: Router) { + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + this.metricsClicked = false; + this.statsClicked = false; + this.fetchPublications = new FetchPublications( this._searchPublicationsService); + this.fetchDatasets = new FetchDatasets(this._searchDatasetsService); + this.fetchSoftware = new FetchSoftware(this._searchSoftwareService); + + this.updateTitle("Project"); + this.updateDescription("project, funding, open access, publications, research data, software"); + + this.projectId = params['projectId']; + if(this.projectId){ + this.publications_dynamic = + ""; + + this.datasets_dynamic = + ""; + + this.software_dynamic = + ""; + + this.getProjectInfo(this.projectId); + this.searchPublications(); + this.fetchDatasets.getNumForEntity("project", this.projectId); + this.fetchSoftware.getNumForEntity("project", this.projectId); + }else{ + this.showLoading = false; + this.warningMessage="No valid project id"; + } + + this.downloadURLAPI = OpenaireProperties.getCsvAPIURL(); + + this.createClipboard(); + this.csvParams = "format=csv-special&page=0&type=publications&query=(((oaftype exact result) and (resulttypeid exact publication)) and (relprojectid exact "+this.projectId+"))&size="; + this.csvParamsDatasets = "format=csv-special&page=0&type=datasets&query=(((oaftype exact result) and (resulttypeid exact dataset)) and (relprojectid exact "+this.projectId+"))&size="; + this.csvParamsSoftware = "format=csv-special&page=0&type=software&query=(((oaftype exact result) and (resulttypeid exact software)) and (relprojectid exact "+this.projectId+"))&size="; + + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + }); +} + + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.infoSub) { + this.infoSub.unsubscribe(); + } + if(this.downloadFilePiwikSub) { + this.downloadFilePiwikSub.unsubscribe(); + } + } + + private createClipboard() { + if(typeof window !== 'undefined') { + + let publ_clipboard, datasets_clipboard, software_clipboard; + let Clipboard; + Clipboard = require('clipboard'); + publ_clipboard = new Clipboard('.publ_clipboard_btn'); + datasets_clipboard = new Clipboard('.datasets_clipboard_btn'); + software_clipboard = new Clipboard('.software_clipboard_btn'); + } + } + + private searchPublications() { + this.fetchPublications.getResultsForEntity("project", this.projectId, 1, 10); + this.linkToSearchPublications = OpenaireProperties.getLinkToAdvancedSearchPublications();// + "?project=" + this.projectId+"&pr=and"; + if(this.fetchPublications.searchUtils.totalResults > 0) { + //this.activeTab = "Publications"; + } else { + //this.searchDatasetsInit(); + } + } + + private searchDatasets() { + this.fetchDatasets.getResultsForEntity("project", this.projectId, 1, 10); + this.linkToSearchDatasets = OpenaireProperties.getLinkToAdvancedSearchDatasets();// + "?project=" + this.projectId+"&pr=and"; + + this.reloadDatasets = false; + //this.activeTab = "Research Data"; + } + + private searchSoftware() { + this.fetchSoftware.getResultsForEntity("project", this.projectId, 1, 10); + this.linkToSearchSoftware = OpenaireProperties.getLinkToAdvancedSearchSoftware(); + this.reloadSoftware = false; + } + + public searchDatasetsInit() { + console.info("searchDatasetsInit"); + if(this.reloadDatasets && this.fetchDatasets.searchUtils.totalResults > 0) { + this.searchDatasets(); + } else if(this.fetchDatasets.searchUtils.totalResults == 0) { + //this.statsClicked=true; + //this.activeTab = "Statistics"; + } + } + + public searchSoftwareInit() { + console.info("searchSoftwareInit"); + if(this.reloadSoftware && this.fetchSoftware.searchUtils.totalResults > 0) { + this.searchSoftware(); + } + } + + private getProjectInfo (id:string) { + this.warningMessage = ''; + this.errorMessage="" + this.showLoading = true; + + this.infoSub = this._projectService.getProjectInfo(id).subscribe( + data => { + this.projectInfo = data; + + this.projectName = this.projectInfo.acronym; + if(this.projectName == undefined || this.projectName == '') { + this.projectName = this.projectInfo.title; + } + this.updateTitle(this.projectName); + this.updateDescription("project, funding, open access, publications, research data, "+this.projectName+ ","+this.projectInfo.funder); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.projectName).subscribe(); + } + + this.project= { funderId: "", funderName: this.projectInfo.funder, projectId: this.projectId, projectName: this.projectInfo.title, projectAcronym: this.projectInfo.acronym, startDate: this.projectInfo.startDate, endDate: this.projectInfo.endDate }; + + this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"projRepoViews","projTitle":"'+this.projectId+'","table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":"","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[]}]&info_types=["column"]&stacking=&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(124, 181, 236, 1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false'; + + this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"projRepoDownloads","projTitle":"'+this.projectId+'","table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":"","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[]}]&info_types=["column"]&stacking=&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(124, 181, 236, 1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false'; + + //stats tab charts + this.chartScientificResultsUrl='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"projScient","projTitle":"'+this.projectId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "spline", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Results"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [" "], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.chartAccessModeUrl='https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"projOA","projTitle":"'+this.projectId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "pie", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Results"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [" "], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + this.chartDatasourcesUrl= 'https://beta.openaire.eu/stats/chart.php?com=query&persistent=false&data={"query":"projPubsRepos","projTitle":"'+this.projectId+'", "table": "result", "fields": [{"fld": "number", "agg": "count", "type": "bar", "yaxis":1, "c":false}], "xaxis":{"name": "result_classifications-type", "agg": "avg"}, "group": "", "color": "", "type": "chart", "size":30, "sort": "xaxis", "xStyle":{"r": "-", "s": "-", "l": "-", "ft": "-", "wt": "-"}, "yaxisheaders": [""], "fieldsheaders": ["Research Results"], "in": [], "filters": [{"name": "result_datasources-datasource-name", "values": [" "], "to": "-1"}], "having": [], "incfilters": [], "inchaving": [], "title": "", "subtitle": "", "xaxistitle": ""}&w=600&h=250'; + + this.showLoading = false; + }, + err => { + console.log(err); + this.errorMessage = 'No project found'; + this.showLoading = false; + } + ); + } + + public downloadfile(url:string){ + this.openLoading(); + this.setMessageLoading("Downloading CSV file"); + + this._reportsService.downloadCSVFile(url).subscribe( + data => { + this.closeLoading(); + window.open(window.URL.createObjectURL(data)); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.downloadFilePiwikSub = this._piwikService.trackDownload(url).subscribe(); + } + }, + error => { + console.log("Error downloading the file."); + this.closeLoading(); + this.confirmOpenCsvError(); + }, + () => console.log('Completed file download.') + ); + } + +/* + showHTML(){ + let info:string = "

Publications of Project "; + + if(this.projectInfo.title != undefined && this.projectInfo.title != "") { + info += this.projectInfo.title; + } + if((this.projectInfo.title != undefined && this.projectInfo.title != "") && + ((this.projectInfo.acronym != undefined && this.projectInfo.acronym != "") || + (this.projectInfo.callIdentifier != undefined && this.projectInfo.callIdentifier != ""))) { + info += "("; + } + if(this.projectInfo.acronym != undefined && this.projectInfo.acronym != "") { + info += this.projectInfo.acronym + " - "; + } + if(this.projectInfo.callIdentifier != undefined && this.projectInfo.callIdentifier != "") { + info += this.projectInfo.callIdentifier; + } + if((this.projectInfo.title != undefined && this.projectInfo.title != "") && + ((this.projectInfo.acronym != undefined && this.projectInfo.acronym != "") || + (this.projectInfo.callIdentifier != undefined && this.projectInfo.callIdentifier != ""))) { + info += ")"; + } + info +="

"; + info += "

"+this.fetchPublications.searchUtils.totalResults+" publications

"; + + let htmlParams = 'resources?format=html&page=0&size='+this.fetchPublications.searchUtils.totalResults+'&type=publications&query=(((oaftype exact result) and (resulttypeid exact publication)) and (relprojectid exact "'+this.projectId+'"))'; + this._reportsService.downloadHTMLFile(this.downloadURLAPI+htmlParams, info) + .subscribe(data => this.funct(data), + error => console.log("Error downloading the file."), + () => console.log('Completed file download.')); + } + + funct(data) { + var win = window.open(window.URL.createObjectURL(data)); + } +*/ + public metricsResults($event) { + this.totalViews = $event.totalViews; + this.totalDownloads = $event.totalDownloads; + this.pageViews = $event.pageViews; + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + private openLoading(){ + if(this.loading){ + this.loading.open(); + } + } + private closeLoading(){ + if(this.loading){ + this.loading.close(); + } + } + private setMessageLoading(message: string){ + if(this.loading){ + this.loading.message = message; + } + } + + public confirmOpenCsvError(){ + this.alertCsvError.cancelButton = false; + this.alertCsvError.okButton = true; + this.alertCsvError.alertTitle = "ERROR DOWNLOADING CSV FILE"; + this.alertCsvError.message = "There was an error in csv downloading. Please try again later."; + this.alertCsvError.okButtonText = "OK"; + this.alertCsvError.open(); + } +} diff --git a/landingPages/project/project.module.ts b/landingPages/project/project.module.ts new file mode 100644 index 00000000..d7156d0a --- /dev/null +++ b/landingPages/project/project.module.ts @@ -0,0 +1,45 @@ +//import {MaterialModule} from '@angular/material'; +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import { ProjectServiceModule} from './projectService.module'; +// import {HtmlProgressReportService} from './htmlProgressReport.service'; +import{LoadingModalModule} from '../../utils/modal/loadingModal.module'; +import {AlertModalModule} from '../../utils/modal/alertModal.module'; +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +import { ProjectComponent } from './project.component'; +// import { ProjectRoutingModule } from './project-routing.module'; +import {IFrameModule} from '../../utils/iframe.module'; +import {MetricsModule} from '../landing-utils/metrics.module'; +import {ReportsServiceModule} from '../../services/reportsService.module'; +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import {SoftwareServiceModule} from '../../services/softwareService.module'; +import {TabResultModule } from '../../searchPages/searchUtils/tabResult.module'; +import { LandingModule } from '../landing-utils/landing.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, LandingModule, + LoadingModalModule, AlertModalModule, ErrorMessagesModule, + TabResultModule, IFrameModule, MetricsModule, ReportsServiceModule, + PublicationsServiceModule, DatasetsServiceModule, SoftwareServiceModule, ProjectServiceModule + ], + declarations: [ + ProjectComponent + ], + providers:[ + // ProjectService, + // HtmlProgressReportService + FreeGuard, IsRouteEnabled + ], + exports: [ + ProjectComponent + ] +}) +export class ProjectModule { } diff --git a/landingPages/project/project.service.ts b/landingPages/project/project.service.ts new file mode 100644 index 00000000..57b57d90 --- /dev/null +++ b/landingPages/project/project.service.ts @@ -0,0 +1,207 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {ProjectInfo} from '../../utils/entities/projectInfo'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + +import { ParsingFunctions } from '../landing-utils/parsingFunctions.class'; + +@Injectable() +export class ProjectService { + + constructor(private http: Http ) { + this.parsingFunctions = new ParsingFunctions(); + } + + public parsingFunctions: ParsingFunctions; + projectInfo: ProjectInfo; + + getProjectInfo (id: string):any { + console.info("getProjectInfo in service"); + + let url = OpenaireProperties. getSearchAPIURLLast() + 'projects/'+id+"?format=json"; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => res['result']['metadata']['oaf:entity']['oaf:project']) + .map(res => [res, + res['fundingtree'], + res['rels']['rel']]) + .map(res => this.parseProjectInfo(res)); + + } + + /* + get project strtDate and endDate + */ + getProjectDates (id: string):any { + + let url = OpenaireProperties. getSearchAPIURLLast()+'projects/'+id+"?format=json"; + let key = url+'_projectDates'; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => res['result']['metadata']['oaf:entity']['oaf:project']) + .map(res => [res, + res['fundingtree'], + res['rels']['rel']]) + .map(res => this.parseProjectDates(id,res)) + + } + + getHTMLInfo(id: string): any { + let url = OpenaireProperties. getSearchAPIURLLast() + 'projects/'+id+"?format=json"; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => res['result']['metadata']['oaf:entity']['oaf:project']) + .map(res => this.parseHTMLInfo(res)); + } + + 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.log(error); + return Observable.throw(error || 'Server error'); + } + + parseHTMLInfo (data: any):any { + let htmlInfo: {"title": string, "acronym": string, "callIdentifier": string}; + + if(data != null) { + htmlInfo = {"title": data.title, "acronym": data.acronym, "callIdentifier": data.callidentifier}; + } + return htmlInfo; + } + + parseProjectInfo (data: any):any { + this.projectInfo = new ProjectInfo(); + + if(data[0] != null) { + this.projectInfo.acronym = data[0].acronym; + if(Array.isArray(data[0]['title'])) { + this.projectInfo.title = data[0].title[0]; + } else { + this.projectInfo.title = data[0].title; + } + this.projectInfo.callIdentifier = data[0].callidentifier; + this.projectInfo.contractNum = data[0].code; + this.projectInfo.startDate = data[0].startdate; + this.projectInfo.endDate = data[0].enddate; + this.projectInfo.openAccessMandate = data[0].oamandatepublications; + this.projectInfo.specialClause39 = data[0].ecsc39; + } + if(data[1] != null) { + /* + if(data[1]['funder'] != null) { + this.projectInfo.funder = data[1]['funder'].shortname; + } + + let funding; + this.projectInfo.funding = ""; + + if(data[1]['funding_level_2'] != null) { + funding = data[1]['funding_level_2'].id; + } else if(data[1]['funding_level_1'] != null) { + funding = data[1]['funding_level_1'].id; + } else if(data[1]['funding_level_0'] != null) { + funding = data[1]['funding_level_0'].id; + } + + if(funding != undefined) { + funding = funding.split("::"); + for(let i=1; i(); + + let acronym: string = ""; + let name: string = ""; + let id: string = ""; + + if(!Array.isArray(data[2])) { + if(data[2].hasOwnProperty("legalshortname")) { + acronym = data[2].legalshortname; + } + if(data[2].hasOwnProperty("legalname")) { + name = data[2].legalname; + } + if(!acronym && !name){ + // acronym is displayed with link and name only in tooltip + acronym = "[no title available]"; + } + + if(data[2].hasOwnProperty("to")) { + id = data[2]['to'].content; + } + + this.projectInfo.organizations.push({"acronym": acronym, "name": name, "id": id}); + } else { + for(let i=0; i +
+
+ +
+ + + + +
+
+ + {{publicationInfo.types.join(", ")}} + {{publicationInfo.languages.join(", ")}} + {{publicationInfo.title.accessMode}} + + + + Record in preview + + + + + +
+ + ({{publicationInfo.date}}) +
+ +
    +
  • Publisher: {{publicationInfo.publisher}}
  • +
  • + Journal: + {{publicationInfo.journal['journal']}} + + ( + + + issn: {{publicationInfo.journal['issn']}} + + + lissn: {{publicationInfo.journal['lissn']}} + + + ) + +
  • + +
  • Embargo end date: {{publicationInfo.embargoEndDate}}
  • +
  • + +
  • +
  • + + +
  • +
+ +
+ {{publicationInfo.description}} +
+ + + + + + + + + + + + + + + + + +
+
+
+ No references available +
+ +
+ + +
+ {{publicationInfo.references.length}} references, page {{referencesPage}} of {{totalPages(publicationInfo.references.length)}} + +
+ +
+

+ + {{item['name']}} + +

+

+ {{item['name']}} +

+
+ + + + + +
+
+ +
+
+ No related research results available +
+
+
+
{{provenanceaction}}
+ + +
+
+
+ + +
+
+ No similar research results available +
+
+ + +
+
+ +
+
+ No related organizations available +
+
+
+ {{publicationInfo.organizations.length}} organizations, page {{organizationsPage}} of {{totalPages(publicationInfo.organizations.length)}} + +
+ + + + + + + + + +
+ + {{organization['name']}} + ( + {{organization.shortname}} + ) + +

+ {{organization['name']}} + ( + {{organization.shortname}} + ) +

+
{{organization.country}}
+
Website url: + {{organization.websiteUrl}} +
+
+
+
{{organization['trust']}}%
+ +
+
+

no trust available

+
+
+ + +
+
+ +
+
+ {{bioentitiesNum}} bioentities, page {{bioentitiesPage}} of {{totalPages(bioentitiesNum)}} + +
+ + + + + + + + + + + + + +
+ + + {{keyIn}} + + + + {{key}} +
+
+
+
+ {{publicationInfo.software.length}} software results, page {{softwarePage}} of {{totalPages(publicationInfo.software.length)}} + +
+ + + + + + + + +
+ + + {{item.name}} + + +
+
+
+ + + + + + + + +
+ +
+
+ +
+
+
+ Share - Bookmark + +
+ + +
    + + + +
  • + +
  • +
  • + +
  • + +
  • +
    +
    Related to
    +
    + + {{item['labelContext']}} + -> {{item['labelCategory']}} + : {{item['labelConcept']}} + + + {{item['labelContext']}} + -> {{item['labelCategory']}} + : {{item['labelConcept']}} + +
    +
    + +
  • +
  • +
      +
    • +
      + Cite this publication +
      +
      + +
      +
    • +
    + +
  • +
  • + + + +
  • +
+
+
+
+
+
+
+
diff --git a/landingPages/publication/publication.component.ts b/landingPages/publication/publication.component.ts new file mode 100644 index 00000000..b44a14c6 --- /dev/null +++ b/landingPages/publication/publication.component.ts @@ -0,0 +1,312 @@ +import {Component, ViewChild, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {PublicationService} from './publication.service'; +import {PublicationInfo} from '../../utils/entities/publicationInfo'; +import {ActivatedRoute, Router} from '@angular/router'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../utils/routerHelper.class'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +import { Meta} from '../../../angular2-meta'; + + + +@Component({ + selector: 'publication', + templateUrl: 'publication.component.html', + +}) + +export class PublicationComponent { + public publicationInfo: PublicationInfo; + public articleId: string; + + // APP BOX variables + public showAllCollectedFrom: boolean = false; + public showAllDownloadFrom: boolean = false; + + // Metrics tab variables + public metricsClicked: boolean; + public viewsFrameUrl: string; + public downloadsFrameUrl: string; + public totalViews: number; + public totalDownloads: number; + public pageViews: number; + + // Custom tab paging variables + public referencesPage: number = 1; + public organizationsPage: number = 1; + public softwarePage: number = 1; + public bioentitiesPage: number = 1; + public pageSize: number = 10; + /* + public startt: number = 0; + public stopp: number = 0; + */ + + // Active tab variable for responsiveness + public activeTab: string = "References"; + + // Map counting variables + public bioentitiesNum: number = 0; + public relatedResearchResultsNum: number = 0; + + // Message variables + public warningMessage = ""; + public errorMessage = ""; + public showLoading: boolean = true; + + public routerHelper:RouterHelper = new RouterHelper(); + + private doi: string; + private result; + sub: any; piwiksub: any; infoSub: any; + + constructor ( private element: ElementRef, + private _publicationService: PublicationService, + private _piwikService:PiwikService, + private route: ActivatedRoute, private _meta: Meta, + private _router: Router) { + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(data => { + this.publicationInfo = null; + this.updateTitle("Publication"); + this.updateDescription("Publication, open access, collected from"); + + this.articleId = data['articleId']; + console.info("Article id is :"+this.articleId); + + this.metricsClicked = false; + + if(this.articleId){ + + this.getPublicationInfo(this.articleId); + // if (typeof document !== 'undefined') { + // switcher(UIkit); + // } + }else{ + this.showLoading = false; + this.warningMessage="No valid publication id"; + } + + this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoViews", "resTitle":"'+this.articleId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":" ","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"Repository","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false'; + + this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoDownloads", "resTitle":"'+this.articleId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":" ","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"Repository","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false'; + + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + }); + } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.infoSub) { + this.infoSub.unsubscribe(); + } + } + + private getPublicationInfo(id:string) { + this.warningMessage = ''; + this.errorMessage="" + this.showLoading = true; + + this.infoSub = this._publicationService.getPublicationInfo(this.articleId).subscribe( + data => { + this.publicationInfo = data; + + // this.result = [] + // this.result = {id: id, type :"dataset", source : "openaire", title: this.publicationInfo.title,url: '', result: '', accessRights: this.publicationInfo.bestaccessright, embargoEndDate: ''}; + this.updateTitle(this.publicationInfo.title.name); + this.updateDescription("Dataset, search, repositories, open access,"+this.publicationInfo.title.name); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.publicationInfo.title.name).subscribe(); + } + + let bioentitiesNum = 0; + if(this.publicationInfo.bioentities != undefined) { + this.publicationInfo.bioentities.forEach(function (value, key, map) { + bioentitiesNum += value.size; + }); + } + this.bioentitiesNum = bioentitiesNum; + + let relatedResearchResultsNum = 0; + if(this.publicationInfo.relatedResearchResults != undefined) { + this.publicationInfo.relatedResearchResults.forEach(function (value, key, map) { + relatedResearchResultsNum += value.length; + }); + } + this.relatedResearchResultsNum = relatedResearchResultsNum; + + this.result = {id: this.articleId, type :"publication", source : "openaire", title: this.publicationInfo.title,url: '', result: '', accessRights: this.publicationInfo.title.accessMode, embargoEndDate: ''}; + // this.result.push(result_); + + if(this.publicationInfo.identifiers != undefined && this.publicationInfo.identifiers.has('doi')) { + this.doi = this.publicationInfo.identifiers.get('doi')[0]; + } + + this.showLoading = false; + + if(this.publicationInfo.references) { + this.activeTab = "References"; + } else if(this.publicationInfo.relatedResearchResults) { + this.activeTab = "Related Research Results"; + } else if(this.publicationInfo.similarResearchResults) { + this.activeTab = "Similar Research Results"; + } else if(this.publicationInfo.organizations) { + this.activeTab = "Related Organizations"; + } else if(this.publicationInfo.bioentities) { + this.activeTab = "bioentities"; + } else if(this.publicationInfo.software) { + this.activeTab = "Software"; + } else { + this.activeTab = "Metrics"; + this.metricsClicked = true; + } + console.info("activeTab is "+this.activeTab); + }, + err => { + console.log(err); + console.info("error"); + + this.errorMessage = 'No publication found'; + this.showLoading = false; + } + ); + } + + public metricsResults($event) { + this.totalViews = $event.totalViews; + this.totalDownloads = $event.totalDownloads; + this.pageViews = $event.pageViews; + } + + public buildCurationTooltip() { + let tooltipContent: string = "
"; + + tooltipContent += "

Record in preview

"; + tooltipContent += "

Bibliographic record accepted by the system, but not yet processed by
OpenAIRE tools for information quality improvement and de-duplication

"; + + return tooltipContent+= "
"; + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + public totalPages(totalResults: number): number { + let totalPages:any = totalResults/this.pageSize; + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, this.pageSize) + 1); + } + return totalPages; + } + + public updateReferencesPage($event) { + this.referencesPage = $event.value; + } + + public updateOrganizationsPage($event) { + this.organizationsPage = $event.value; + } + + public updateSoftwarePage($event) { + this.softwarePage = $event.value; + } + + public updateBioentitiesPage($event) { + this.bioentitiesPage = $event.value; + } + + public keysToArray(bioentities: Map) : string[] { + let keys: string[] = []; + bioentities.forEach(function (value, key, map) { + keys.push(key); + }); + return keys; + } + public getKeys( map) { + return Array.from(map.keys()); + } +/* + start(i: number, bioentitiesPage: number) { + let sum = 0; + let index=0; + let retValue = 0; + let valuesToPage = this.pageSize*bioentitiesPage; + let valuesToPreviousPage = valuesToPage - this.pageSize; + + if(bioentitiesPage == 1) { + return 0; + } + + this.publicationInfo.bioentities.forEach(function (value, key, map) { + sum += map.get(key).size; + + if(index == i) { + if(sum <= valuesToPreviousPage) { + retValue = 0; + } else if((sum-map.get(key).size) >= valuesToPage){ + retValue = 0; + } else { + if(map.get(key).size < (sum - valuesToPreviousPage)) { + retValue = 0; + } else { + retValue = map.get(key).size - (sum - valuesToPreviousPage); + } + } + } + index++; + }); + this.startt = retValue; + return retValue; + } + + stop(i: number, bioentitiesPage: number) { + let sum = 0; + let index=0; + let retValue = 0; + let valuesToPage = this.pageSize*bioentitiesPage; + let valuesToPreviousPage = valuesToPage - this.pageSize; + + this.publicationInfo.bioentities.forEach(function (value, key, map) { + sum += map.get(key).size; + if(index == i) { + if(sum <= valuesToPreviousPage) { + retValue = 0; + } else if((sum - map.get(key).size) >= valuesToPage){ + retValue = 0; + } else { + if(sum < valuesToPage) { + retValue = map.get(key).size; + } else { + retValue = map.get(key).size - (sum - valuesToPage); + } + } + } + index++; + }); + this.stopp = retValue; + return retValue; + } +*/ + +} diff --git a/landingPages/publication/publication.module.ts b/landingPages/publication/publication.module.ts new file mode 100644 index 00000000..b2dd29c6 --- /dev/null +++ b/landingPages/publication/publication.module.ts @@ -0,0 +1,32 @@ +//import {MaterialModule} from '@angular/material'; +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { SharedModule } from '../../shared/shared.module'; +import { RouterModule } from '@angular/router'; + +import { PublicationService} from './publication.service'; +import { PublicationComponent } from './publication.component'; +// import { PublicationRoutingModule } from './publication-routing.module'; +import {MetricsModule} from '../landing-utils/metrics.module'; +import {IFrameModule} from '../../utils/iframe.module'; +import {AltMetricsModule} from '../../utils/altmetrics.module'; +import {CiteThisModule} from '../landing-utils/citeThis/citeThis.module'; +import {PagingModule} from '../../utils/paging.module'; + +import { ResultLandingModule } from '../landing-utils/resultLanding.module'; +import { LandingModule } from '../landing-utils/landing.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; +import {MetaModule} from '../../../meta.module'; +import { ConfigurationServiceModule } from '../../utils/configuration/configurationService.module'; +@NgModule({ + imports: [ + CommonModule, FormsModule, LandingModule,SharedModule, RouterModule, CiteThisModule, PagingModule, + ResultLandingModule, IFrameModule, MetricsModule, AltMetricsModule, + MetaModule, ConfigurationServiceModule], + declarations: [PublicationComponent], + providers:[PublicationService, FreeGuard, IsRouteEnabled], + exports: [PublicationComponent] +}) +export class PublicationModule { } diff --git a/landingPages/publication/publication.service.ts b/landingPages/publication/publication.service.ts new file mode 100644 index 00000000..2aabb215 --- /dev/null +++ b/landingPages/publication/publication.service.ts @@ -0,0 +1,339 @@ + +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {PublicationInfo} from '../../utils/entities/publicationInfo'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import 'rxjs/add/operator/map'; + + +import { ParsingFunctions } from '../landing-utils/parsingFunctions.class'; + +@Injectable() +export class PublicationService { + + constructor(private http: Http ) { + this.parsingFunctions = new ParsingFunctions(); + } + + public parsingFunctions: ParsingFunctions; + publicationInfo: PublicationInfo; + + getPublicationInfo (id: string):any { + console.info("getPublicationInfo in service"); + let url = OpenaireProperties. getSearchAPIURLLast() + 'publications/' +id+"?format=json"; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['result']['header']['dri:status'], res['result']['metadata']['oaf:entity']]) + .map(res => [ res[1]['oaf:result'], + res[1]['oaf:result']['title'], + res[1]['oaf:result']['rels']['rel'], + res[1]['oaf:result']['children'], + res[1]['oaf:result']['pid'], + res[1]['oaf:result']['journal'], + res[1]['oaf:result']['language'], + res[1]['oaf:result']['subject'], + res[1]['oaf:result']['bestaccessright'], + res[1]['oaf:result']['collectedfrom'], + (res[1]['extraInfo']!= undefined && res[1]['extraInfo']['citations']!= undefined)? res[1]['extraInfo']['citations']['citation']:null, + res[1]['oaf:result']['context'], + res[0], + res[1]['oaf:result']['creator'] + ]) + .map(res => this.parsePublicationInfo(res)); + } + + 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.log(error); + return Observable.throw(error || 'Server error'); + } + + parsePublicationInfo (data: any):any { + this.publicationInfo = new PublicationInfo(); + + if(data[0] != null) { + var date:string = (data[0].dateofacceptance)+""; // transform to string in case it is an integer + this.publicationInfo.date = (date && (date).indexOf('-') !== -1)?date.split('-')[0]:date; + this.publicationInfo.dateofacceptance = data[0].dateofacceptance; + this.publicationInfo.publisher = data[0].publisher; + if(!Array.isArray(data[0].description)) { + this.publicationInfo.description = data[0].description; + } else { + this.publicationInfo.description = data[0].description[0]; + } + this.publicationInfo.embargoEndDate = data[0].embargoenddate; + } + + this.publicationInfo.title = {"name": "", "url": "", "accessMode": ""}; + if(data[0]['bestaccessright'].hasOwnProperty("classid")) { + this.publicationInfo.title.accessMode = data[0]['bestaccessright'].classid; + } + + if(data[1] != null) { + if(Array.isArray(data[1])) { + this.publicationInfo.title['name'] = data[1][0].content; + } else { + this.publicationInfo.title['name'] = data[1].content; + } + } + + if(data[2] != null) { + let relation; + let length = Array.isArray(data[2]) ? data[2].length : 1; + + for(let i=0; i(); + //this.publicationInfo.downloadFrom = new Map(); + //this.publicationInfo.publishedIn = new Map(); + + + this.publicationInfo.hostedBy_collectedFrom = new Array<{"downloadName": string, "downloadUrl": string[], "collectedName": string, "collectedId": string, "accessMode": string[], "bestAccessMode": string, "type": string, "year":string}>(); + + + this.publicationInfo.types = new Array(); + let types = new Set(); + + let counter = 0; + let instance; + + let length = Array.isArray(data[3]['instance']) ? data[3]['instance'].length : 1; + + for(let i=0; i>, { "name": string, "url": string}[]] = this.parseBioentitiesAndSoftware(data[3]); + this.publicationInfo.bioentities = externalResults[0]; + this.publicationInfo.software = externalResults[1]; + } + } + + if(data[4] != null) { + this.publicationInfo.identifiers = this.parsingFunctions.parseIdentifiers(data[4]); + } + + if(data[5] != null) { + this.publicationInfo.journal = {"journal": "", "issn": "", "lissn": ""} + + this.publicationInfo.journal['journal'] = data[5].content; + this.publicationInfo.journal['issn'] = data[5].issn; + this.publicationInfo.journal['lissn'] = data[5].lissn; + } + + if(data[6] != null) { + this.publicationInfo.languages = new Array(); + + if(!Array.isArray(data[6])) { + if(data[6].classname != "Undetermined" && data[6].classname) { + this.publicationInfo.languages.push(data[6].classname); + } + } else { + for(let i=0; i, Map] = this.parsingFunctions.parseAllSubjects(data[7]); + this.publicationInfo.subjects = subjectResults[0]; + this.publicationInfo.otherSubjects = subjectResults[1]; + this.publicationInfo.classifiedSubjects = subjectResults[2]; + } + + // if(data[8] != null) { + // this.publicationInfo.bestaccessright = data[8].classid; + // } + + // if(data[9] != null) { + // this.publicationInfo.collectedFrom = this.parsingFunctions.parseCollectedFrom(data[9]); + // } + + this.publicationInfo.hostedBy_collectedFrom = this.parsingFunctions.addPublisherToHostedBy_collectedFrom( + this.publicationInfo.hostedBy_collectedFrom, this.publicationInfo.publisher, + this.publicationInfo.journal, this.publicationInfo.identifiers, + this.publicationInfo.title); + + if(data[10] != null) { + this.publicationInfo.references = this.parseReferences(data[10]); + } + + if(data[11] != null) { + this.publicationInfo.contexts = this.parsingFunctions.parseContexts(data[11]); + } + + if(data[12] != null && data[12] == "under curation") { + this.publicationInfo.underCurationMessage = true; + } else { + this.publicationInfo.underCurationMessage = false; + } + + if(data[13] != null) { + if(this.publicationInfo.authors == undefined) { + this.publicationInfo.authors = new Array(); + } + + let authors = data[13]; + let length = Array.isArray(authors) ? authors.length : 1; + + for(let i=0; i(); + } + + let organization: { "name": string, "shortname": string, + "id": string, "websiteUrl": string, + "country": string, "trust": number + } = { + "name": "", "shortname": "", + "id": "", "websiteUrl": "", + "country": "", "trust": null + }; + + organization.id = relation['to'].content; + organization.name = relation.legalname; + organization.shortname = relation.legalshortname; + organization.websiteUrl = relation.websiteurl; + if(relation.country) { + organization.country = relation.country.classname; + } + if(relation.trust) { + organization.trust = Math.round(relation.trust*100); + } + + organizations.push(organization); + return organizations; + } + + parseBioentitiesAndSoftware(children: any) : [Map>, { "name": string, "url": string}[]] { + let bioentities: Map>; + let software: {"name": string, "url": string}[]; + + let length = Array.isArray(children['externalreference']) ? children['externalreference'].length : 1; + + let externalreference; + for(let i=0; i>(); + } + + if(!bioentities.has(externalreference.sitename)) { + bioentities.set(externalreference.sitename, new Map()); + } + bioentities.get(externalreference.sitename).set(externalreference.refidentifier, externalreference.url); + + } else if(externalreference['qualifier'].classid == "software") { + + if(software == undefined) { + software = new Array<{"name": string, "url": string}>(); + } + + software.push({"name": externalreference.sitename, "url": externalreference.url}); + } + } + } + + return [bioentities, software]; + } + + parseReferences(citations: any): {"name": string, "url": string}[] { + let references = new Array<{"name": string, "url": string}>(); + + let citation; + let length = Array.isArray(citations) ? citations.length : 1; + for(let i=0; i +
+
+ +
+ + + + + +
+
+ + {{softwareInfo.types.join(", ")}} + {{softwareInfo.languages.join(", ")}} + {{softwareInfo.title.accessMode}} + + + Record in preview + + + + +
+ + ({{softwareInfo.date}}) +
+ +
    +
  • Publisher: {{softwareInfo.publisher}}
  • + +
  • Embargo end date: {{softwareInfo.embargoEndDate}}
  • +
  • + +
  • +
  • + + +
  • +
+ +
+ {{softwareInfo.description}} +
+ + + + + + + + + + + +
+
+
+ No related research results available +
+
+
+
{{provenanceaction}}
+ + +
+
+
+ +
+
+ No similar research results available +
+
+ +
+
+
+ + + + + + + +
+ +
+
+ +
+
+
+ Share - Bookmark + +
+ + +
    + +
  • + +
  • +
  • + +
  • + +
  • +
    +
    Related to
    +
    + + {{item['labelContext']}} + -> {{item['labelCategory']}} + : {{item['labelConcept']}} + + + {{item['labelContext']}} + -> {{item['labelCategory']}} + : {{item['labelConcept']}} + +
    + +
    + +
  • +
  • +
      +
    • +
      + Cite this software +
      +
      + +
      +
    • +
    + + +
  • +
  • + +
  • + +
+ +
+
+
+
+
+
+
diff --git a/landingPages/software/software.component.ts b/landingPages/software/software.component.ts new file mode 100644 index 00000000..9e2456b3 --- /dev/null +++ b/landingPages/software/software.component.ts @@ -0,0 +1,172 @@ +import {Component, ViewChild, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {SoftwareService} from './software.service'; +import {SoftwareInfo} from '../../utils/entities/softwareInfo'; +import {ActivatedRoute, Router} from '@angular/router'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties' +import {RouterHelper} from '../../utils/routerHelper.class'; +import { Meta} from '../../../angular2-meta'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'software', + templateUrl: 'software.component.html', +}) + +export class SoftwareComponent { + public softwareInfo: SoftwareInfo; + public softwareId : string ; + + // APP BOX variables + public showAllCollectedFrom: boolean = false; + public showAllDownloadFrom: boolean = false; + public showAllPublishedIn: boolean = false; + + // Metrics tab variables + public metricsClicked: boolean; + public viewsFrameUrl: string; + public downloadsFrameUrl: string; + public totalViews: number; + public totalDownloads: number; + public pageViews: number; + + // Active tab variable for responsiveness + public activeTab: string = "Related Research Results"; + + // Map counting variable + public relatedResearchResultsNum: number = 0; + + // Message variables + public warningMessage = ""; + public errorMessage = ""; + public showLoading: boolean = true; + + public routerHelper:RouterHelper = new RouterHelper(); + + private result ; + sub: any; piwiksub: any; infoSub: any; + + constructor (private element: ElementRef, + private _softwareService: SoftwareService, + private _piwikService:PiwikService, + private route: ActivatedRoute, + private _meta: Meta, + private _router: Router) { + this.updateUrl(OpenaireProperties.getBaseLink()+this._router.url); + } + + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + this.softwareInfo = null; + this.updateTitle("Software"); + this.updateDescription("Software, search, open access"); + + this.softwareId = params['softwareId']; + console.info("Id is :"+this.softwareId); + + if(this.softwareId){ + this.getSoftwareInfo(this.softwareId); + }else{ + this.showLoading = false; + this.warningMessage="No valid software id"; + } + + this.metricsClicked = false; + + this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoViews", "resTitle":"'+this.softwareId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":" ","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"Repository","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false'; + /*this.viewsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resViewsTimeline", "resTitle":"'+this.softwareId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":" ","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"Repository","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(124, 181, 236, 1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false'; + */ + + this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoDownloads", "resTitle":"'+this.softwareId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":" ","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"Repository","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false'; + /*this.downloadsFrameUrl = OpenaireProperties.getFramesAPIURL()+'merge.php?com=query&data=[{"query":"resRepoDownloadTimeline", "resTitle":"'+this.softwareId+'", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":" ","color":"","type":"chart","size":30,"sort":"xaxis","xStyle":{"r":-30,"s":"0","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"Repository","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true'; + */ + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + }); + + } + + ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + if(this.infoSub) { + this.infoSub.unsubscribe(); + } + } + + private getSoftwareInfo(id:string) { + this.warningMessage = ''; + this.errorMessage="" + this.showLoading = true; + + this.infoSub = this._softwareService.getSoftwareInfo(id).subscribe( + data => { + this.softwareInfo = data; + this.updateTitle(this.softwareInfo.title.name); + this.updateDescription("Software, search, repositories, open access,"+this.softwareInfo.title.name); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.softwareInfo.title.name).subscribe(); + } + + this.result = [] + this.result = {id: id, type :"software", source : "openaire", title: this.softwareInfo.title,url: '', result: '', accessRights: this.softwareInfo.title.accessMode, embargoEndDate: ''}; + + let relatedResearchResultsNum = 0; + if(this.softwareInfo.relatedResearchResults != undefined) { + this.softwareInfo.relatedResearchResults.forEach(function (value, key, map) { + relatedResearchResultsNum += value.length; + }); + } + this.relatedResearchResultsNum = relatedResearchResultsNum; + + this.showLoading = false; + }, + err => { + console.log(err) + console.info("error"); + + this.errorMessage = 'No software found'; + this.showLoading = false; + } + ); + } + + // showChange($event) { + // this.showAllReferences=$event.value; + // } + + public metricsResults($event) { + this.totalViews = $event.totalViews; + this.totalDownloads = $event.totalDownloads; + this.pageViews = $event.pageViews; + } + + private updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + private updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + private updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + public buildCurationTooltip() { + let tooltipContent: string = "
"; + + tooltipContent += "

Record in preview

"; + tooltipContent += "

Bibliographic record accepted by the system, but not yet processed by
OpenAIRE tools for information quality improvement and de-duplication

"; + + return tooltipContent; + } + public getKeys( map) { + return Array.from(map.keys()); + } +} diff --git a/landingPages/software/software.module.ts b/landingPages/software/software.module.ts new file mode 100644 index 00000000..6584f9ed --- /dev/null +++ b/landingPages/software/software.module.ts @@ -0,0 +1,36 @@ +//import {MaterialModule} from '@angular/material'; +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { RouterModule } from '@angular/router'; + +import { SoftwareService } from './software.service'; +import { SoftwareComponent } from './software.component'; +// import { SoftwareRoutingModule } from './software-routing.module'; +import { MetricsModule } from '../landing-utils/metrics.module'; +import { IFrameModule } from '../../utils/iframe.module'; +import { AltMetricsModule } from '../../utils/altmetrics.module'; +import { CiteThisModule } from '../landing-utils/citeThis/citeThis.module'; +import { PagingModule } from '../../utils/paging.module'; + +import { ResultLandingModule } from '../landing-utils/resultLanding.module'; +import { LandingModule } from '../landing-utils/landing.module'; +import { FreeGuard } from'../../login/freeGuard.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, LandingModule, RouterModule, CiteThisModule, PagingModule, + ResultLandingModule, IFrameModule, MetricsModule, AltMetricsModule + ], + declarations: [ + SoftwareComponent + ], + providers:[ + SoftwareService, FreeGuard + ], + exports: [ + SoftwareComponent + ] +}) +export class SoftwareModule { } diff --git a/landingPages/software/software.service.ts b/landingPages/software/software.service.ts new file mode 100644 index 00000000..c0fc5806 --- /dev/null +++ b/landingPages/software/software.service.ts @@ -0,0 +1,196 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {SoftwareInfo} from '../../utils/entities/softwareInfo'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + +import { ParsingFunctions } from '../landing-utils/parsingFunctions.class'; + +@Injectable() +export class SoftwareService { + + constructor(private http: Http ) { + this.parsingFunctions = new ParsingFunctions(); + } + + public parsingFunctions: ParsingFunctions; + softwareInfo: SoftwareInfo; + + getSoftwareInfo (id: string):any { + console.info("getSoftwareInfo in service"); + + let url = OpenaireProperties. getSearchAPIURLLast()+'software/'+id+"?format=json"; + let key = url; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .do(res => console.info(res['result']['metadata']['oaf:entity'])) + .map(res => [res['result']['header']['dri:status'], res['result']['metadata']['oaf:entity']['oaf:result']]) + .map(res => [res[1], + res[1]['title'], + res[1]['rels']['rel'], + res[1]['children'], + res[1]['pid'], + res[1]['subject'], + res[1]['bestaccessright'], + res[1]['collectedfrom'], + res[1]['context'], + //res[1]['resulttype'], + res[0], + res[1]['creator'] + ]).map(res => this.parseSoftwareInfo(res)); + } + + 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.log(error); + return Observable.throw(error || 'Server error'); + } + + parseSoftwareInfo (data: any):any { + this.softwareInfo = new SoftwareInfo(); + + if(data[0] != null) { + var date:string = (data[0].dateofacceptance)+""; // transform to string in case it is an integer + this.softwareInfo.date = (date && (date).indexOf('-') !== -1)?date.split('-')[0]:date; + this.softwareInfo.dateofacceptance = data[0].dateofacceptance; + this.softwareInfo.publisher = data[0].publisher; + if(!Array.isArray(data[0].description)) { + this.softwareInfo.description = data[0].description; + } else { + this.softwareInfo.description = data[0].description[0]; + } + this.softwareInfo.embargoEndDate = data[0].embargoenddate; + } + this.softwareInfo.title = {"name": "", "url": "", "accessMode": ""}; + if(data[0]['bestaccessright'] && data[0]['bestaccessright'].hasOwnProperty("classid")) { + this.softwareInfo.title.accessMode = data[0]['bestaccessright'].classid; + } + if(data[1] != null) { + if(Array.isArray(data[1])) { + this.softwareInfo.title['name'] = data[1][0].content; + } else { + this.softwareInfo.title['name'] = data[1].content; + } + } + + if(data[2] != null) { + let relation; + let length = data[2].length!=undefined ? data[2].length : 1; + + for(let i=0; i(); + + this.softwareInfo.types = new Array(); + let types = new Set(); + + let counter = 0; + let instance; + + let length = data[3]['instance'].length!=undefined ? data[3]['instance'].length : 1; + + for(let i=0; i, Map] = this.parsingFunctions.parseAllSubjects(data[5]); + this.softwareInfo.subjects = subjectResults[0]; + this.softwareInfo.otherSubjects = subjectResults[1]; + this.softwareInfo.classifiedSubjects = subjectResults[2]; + } + + // null argument is for journal + this.softwareInfo.hostedBy_collectedFrom = this.parsingFunctions.addPublisherToHostedBy_collectedFrom( + this.softwareInfo.hostedBy_collectedFrom, this.softwareInfo.publisher, + null, this.softwareInfo.identifiers, this.softwareInfo.title); + + if(data[8] != null) { + this.softwareInfo.contexts = this.parsingFunctions.parseContexts(data[8]); + } + + // if(data[9] != null && this.softwareInfo.type == undefined) { + // if(data[9].hasOwnProperty('classname')) { + // this.softwareInfo.type = data[9].classname; + // } + // } + + if(data[9] != null && data[9] == "under curation") { + this.softwareInfo.underCurationMessage = true; + } else { + this.softwareInfo.underCurationMessage = false; + } + + if(data[10] != null) { + if(this.softwareInfo.authors == undefined) { + this.softwareInfo.authors = new Array(); + } + + let authors = data[10]; + let length = Array.isArray(authors) ? authors.length : 1; + + for(let i=0; i | boolean { + var user; + var loggedIn = false; + var isAdmin = false; + var errorCode = ErrorCodes.NOT_LOGGIN; + + if(Session.isLoggedIn()){ + loggedIn = true; + if(!Session.isValidAndRemove()){ + loggedIn = false; + errorCode = ErrorCodes.NOT_VALID; + }else { + isAdmin = Session.isAdminUser(); + if(!isAdmin){ + errorCode = ErrorCodes.NOT_ADMIN; + } + } + }else{ + errorCode =ErrorCodes.NOT_LOGGIN; + } + + if(!loggedIn){ + // this.guardHelper.redirect("/user-info",errorCode,state.url); + this.router.navigate(['/user-info'], { queryParams: { "errorCode": errorCode, "redirectUrl": state.url } }); + + return false; + }else if(!isAdmin){ + // this.guardHelper.redirect("/user-info",errorCode,state.url); + this.router.navigate(['/user-info'], { queryParams: { "errorCode": errorCode, "redirectUrl": state.url } }); + return false; + }else{ + return true; + } + } +} diff --git a/login/freeGuard.guard.ts b/login/freeGuard.guard.ts new file mode 100644 index 00000000..316ff266 --- /dev/null +++ b/login/freeGuard.guard.ts @@ -0,0 +1,36 @@ +import { Injectable } from '@angular/core'; +import { Router,CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router'; +import {Observable} from 'rxjs/Observable'; +import {Session} from './utils/helper.class'; +import {ErrorCodes} from './utils/guardHelper.class'; + +@Injectable() +export class FreeGuard implements CanActivate { + + constructor(private router: Router) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | boolean { + var user; + var valid = true; + var loggedIn = false; + var errorCode = ErrorCodes.NOT_LOGGIN; + + if(Session.isLoggedIn()){ + loggedIn = true; + if(!Session.isValidAndRemove()){ + loggedIn = false; + valid = false; + errorCode = ErrorCodes.NOT_VALID; + } + } + + if(!valid){ + // this.guardHelper.redirect("/user-info",errorCode,state.url); + + this.router.navigate(['/user-info'], { queryParams: { "errorCode": errorCode, "redirectUrl": state.url } }); + return false; + } + return true; + + } +} diff --git a/login/loginGuard.guard.ts b/login/loginGuard.guard.ts new file mode 100644 index 00000000..59999519 --- /dev/null +++ b/login/loginGuard.guard.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@angular/core'; +import { Router,CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router'; +import {Observable} from 'rxjs/Observable'; +import {Session} from './utils/helper.class'; +import {ErrorCodes} from './utils/guardHelper.class'; + +@Injectable() +export class LoginGuard implements CanActivate { + + constructor(private router: Router) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | boolean { + var user; + var loggedIn = false; + var errorCode = ErrorCodes.NOT_LOGGIN; + if(Session.isLoggedIn()){ + loggedIn = true; + if(!Session.isValidAndRemove()){ + loggedIn = false; + errorCode = ErrorCodes.NOT_VALID; + } + }else{ + errorCode = ErrorCodes.NOT_LOGGIN; + } + if(!loggedIn){ + // this.guardHelper.redirect("/user-info",errorCode,state.url); + this.router.navigate(['/user-info'], { queryParams: { "errorCode": errorCode, "redirectUrl": state.url } }); + return false; + }else{ + return true; + } + } +} diff --git a/login/user-routing.module.ts b/login/user-routing.module.ts new file mode 100644 index 00000000..6bbadb82 --- /dev/null +++ b/login/user-routing.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { UserComponent } from './user.component'; +import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: UserComponent, canDeactivate: [PreviousRouteRecorder]}, + + ]) + ] +}) +export class UserRoutingModule { } diff --git a/login/user.component.html b/login/user.component.html new file mode 100644 index 00000000..5f1a52bb --- /dev/null +++ b/login/user.component.html @@ -0,0 +1,54 @@ + +
+
+
+ +
+ + + +
+ The requested page requires authentication. Please sign in. + + Sign in + +
+
+ You are not authorized to use the requested page +
+
+ The session has expired. Please sign in again or continue browsing as a guest. + + Sign in + +
+
{{errorMessage}}
+ +
+
+ Hello {{user.fullname}}! +
+ +
+
+
+
+
diff --git a/login/user.component.ts b/login/user.component.ts new file mode 100644 index 00000000..076c2cd2 --- /dev/null +++ b/login/user.component.ts @@ -0,0 +1,144 @@ +import {Component, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; + +// import {LoginService} from './login.service'; +import {User,Session} from './utils/helper.class'; +import {RouterHelper} from '../utils/routerHelper.class'; +import { Meta} from '../../angular2-meta'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; + +@Component({ + selector: 'user', + templateUrl: 'user.component.html' + }) + +export class UserComponent { + public user: User; + public loggedIn: boolean = false; + public server: boolean = true; + public errorMessage: string; + public username: string = ""; + public password: string = ""; + private sub:any;private sublogin:any; + public errorCode: string = ""; + public redirectUrl: string = ""; + public routerHelper:RouterHelper = new RouterHelper(); + public loginUrl= OpenaireProperties.getLoginURL(); + + constructor( private router: Router, + private route: ActivatedRoute, private _meta: Meta) { + this._meta.setTitle("OpenAIRE | Login"); + } + + ngOnInit() { + if( typeof document !== 'undefined') { + this.server = false; + } + this.loggedIn = Session.isLoggedIn(); + this.user = Session.getUser(); + this.errorMessage = ""; + this.sub = this.route.queryParams.subscribe(params => { + this.errorCode = params["errorCode"]; + this.redirectUrl = params["redirectUrl"]; + this.loggedIn = Session.isLoggedIn(); + this.user = Session.getUser(); + this.errorMessage = ""; + if(this.loggedIn){ + this.redirect(); + } + }); + } + ngOnDestroy(){ + this.sub.unsubscribe(); + if(this.sublogin){ + this.sublogin.unsubscribe(); + } + } + // logout(){ + // if(Session.isLoggedIn()){ + // Session.removeUser(); + // } + // this.loggedIn = false; + // this.user = new User(); + // this.username = ""; + // this.password = ""; + // this.redirect(); + // + // } + redirect(){ + if(this.redirectUrl && this.redirectUrl != null && this.redirectUrl != ""){ + this.redirectUrl = decodeURIComponent(this.redirectUrl); + var baseUrl = this.redirectUrl; + var queryParams = ""; + var paramsArray =[]; + var valuesArray =[]; + if(this.redirectUrl.indexOf('?') != -1){ + baseUrl = this.redirectUrl.split('?')[0]; + queryParams = this.redirectUrl.split('?')[1]; + } + if(queryParams != ""){ + var queryParamsArray = queryParams.split('&'); + for(var i = 0; i < queryParamsArray.length; i++){ + paramsArray.push(queryParamsArray[i].split("=")[0]); + valuesArray.push(queryParamsArray[i].split("=")[1]); + } + this.router.navigate([baseUrl], { queryParams: this.routerHelper.createQueryParams(paramsArray,valuesArray)}); + }else{ + this.router.navigate([baseUrl]); + } + }else{ + this.router.navigate(['/']); + } + } + logIn(){ + if(this.redirectUrl && this.redirectUrl != null && this.redirectUrl != ""){ + this.redirectUrl = decodeURIComponent(this.redirectUrl); + var baseUrl = this.redirectUrl; + var queryParams = ""; + var paramsArray =[]; + var valuesArray =[]; + if(this.redirectUrl.indexOf('?') != -1){ + var splits =this.redirectUrl.split('?'); + if(splits.length>0){ + baseUrl = splits[0]; + } + if(splits.length >1){ + queryParams = splits[1]; + } + } + console.log("saving url & params..."); + console.log(queryParams); + Session.setCurrentUrl(baseUrl); + Session.setCurrentParameters(queryParams); + } + + window.location.href = OpenaireProperties.getLoginURL(); + } + + // login() { + // this.sublogin =this._loginService.authenticate(/*this.user*/this.username, this.password).subscribe( + // data => { + // this.user = data; + // this.loggedIn = true; + // this.username = ""; + // this.password = ""; + // this.errorCode = ""; + // this.redirect(); + // + // }, + // err => { + // console.log(err); + // if(err.status == "404") { + // this.errorMessage = "Wrong username"; + // } else if(err.status == "401") { + // this.errorMessage = "Wrong password"; + // } + // this.username = ""; + // this.password = ""; + // this.errorCode = ""; + // + // } + // ); + // } +} diff --git a/login/user.module.ts b/login/user.module.ts new file mode 100644 index 00000000..676d3fd3 --- /dev/null +++ b/login/user.module.ts @@ -0,0 +1,24 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {UserComponent } from './user.component'; +import { UserRoutingModule } from './user-routing.module'; +import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; +import {FreeGuard} from './freeGuard.guard'; +import {LoginGuard} from './loginGuard.guard'; +import {MetaModule} from '../../meta.module'; + +// import {LoginService} from './login.service'; +@NgModule({ + imports: [ + CommonModule, FormsModule, + UserRoutingModule, MetaModule + + ], + providers:[PreviousRouteRecorder, FreeGuard,LoginGuard ], + declarations: [ + UserComponent +], exports:[UserComponent] +}) +export class UserModule { } diff --git a/login/userMini.component.ts b/login/userMini.component.ts new file mode 100644 index 00000000..f667c138 --- /dev/null +++ b/login/userMini.component.ts @@ -0,0 +1,147 @@ +import {Component, ElementRef, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; +import {Location} from '@angular/common'; +// import {LoginService} from './login.service'; +import {User,Session} from './utils/helper.class'; +import {RouterHelper} from '../utils/routerHelper.class'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {StringUtils} from '../utils/string-utils.class'; +import {LogoutOpenaireService} from './utils/logoutOpenaire.service'; +declare var logoutClicked; +@Component({ + selector: 'user-mini', + template: ` + + +
  • + + + {{user.fullname+" "}} + + + Sign in | Register + + + + +
  • +
    + ` +}) + +export class UserMiniComponent { + public user: User; + public loggedIn: boolean = false; + public isAuthorized: boolean = false; + @Input() public mobileView:boolean = false ; + public server: boolean = true; + public routerHelper:RouterHelper = new RouterHelper(); + + public redirectUrl: string = ""; + private baseUrl = "user-info"; + sub:any; + constructor( private router: Router, private route: ActivatedRoute, private location: Location, private logoutOpenaire: LogoutOpenaireService) {} + + ngOnInit() { + if( typeof document !== 'undefined') { + this.server = false; + } + this.initialize(); + this.sub = this.route.queryParams.subscribe(params => { + this.initialize(); + }); + } + ngOnDestroy(){ + this.sub.unsubscribe(); + } + initialize(){ + this.redirectUrl = this.location.path(); + if(Session.isLoggedIn()){ + if(Session.isUserValid()){ + this.loggedIn = Session.isLoggedIn(); + this.user = Session.getUser(); + if(Session.isAdminUser()){ + this.isAuthorized = true; + }else { + this.isAuthorized = false; + } + + }else{ + Session.removeUser(); + this.loggedIn = false; + this.isAuthorized = false; + this.user = null; + } + }else { + this.loggedIn = false; + this.isAuthorized = false; + this.user = null; + } + + } + gotoUserPage(){ + this.redirectUrl = this.location.path(); + if(this.redirectUrl && this.redirectUrl != null && this.redirectUrl != "" && this.redirectUrl !="user-info"){ + this.router.navigate([this.baseUrl], { queryParams: this.routerHelper.createQueryParam("redirectUrl",this.redirectUrl )}); + }else{ + this.router.navigate([this.baseUrl]); + } + } + logOut(){ + if(Session.isLoggedIn()){ + Session.removeUser(); + // console.log("Try to Logout!"); + // this.logoutOpenaire.logout().subscribe(params => { + // console.log("Logout!"); + // }); + logoutClicked(); + console.log("Redirect to "+location.href); + window.location.href = OpenaireProperties.getLogoutURL()+ StringUtils.URIEncode(location.href); + + } + this.loggedIn = false; + this.isAuthorized = false; + this.user = new User(); + } + + logIn(){ + Session.setCurrentUrl(location.pathname); + Session.setCurrentParameters(location.search); + window.location.href = OpenaireProperties.getLoginURL(); + } + + onClick(id: string) { + var el: HTMLElement = document.getElementById(id); + el.classList.remove('uk-open'); + } + +} diff --git a/login/utils/guardHelper.class.ts b/login/utils/guardHelper.class.ts new file mode 100644 index 00000000..2bee44e6 --- /dev/null +++ b/login/utils/guardHelper.class.ts @@ -0,0 +1,19 @@ + +import { Router} from '@angular/router'; + +// export class GuardHelper{ +// constructor(private router: Router) {} +// +// redirect(url:string, errorCode:number, redirectUrl:string){ +// this.router.navigate([url], { queryParams: { "errorCode": errorCode, "redirectUrl": redirectUrl } }); +// +// } +// +// } +export class ErrorCodes { + public static NOT_LOGGIN:number =1; + public static NOT_ADMIN:number =2; + public static NOT_VALID:number =3; + +} + diff --git a/login/utils/helper.class.ts b/login/utils/helper.class.ts new file mode 100644 index 00000000..0a62a995 --- /dev/null +++ b/login/utils/helper.class.ts @@ -0,0 +1,276 @@ +import {StringUtils} from '../../utils/string-utils.class'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + + +export class User { + email:string; + firstname: string; + lastname: string; + id: string; + fullname: string; + expirationDate: number; + role:string[]; + jwt:string; + +} + +export class Session{ + // public static setUser(user:User): User { + // + // localStorage.setItem("user", JSON.stringify(user)); + // + // return user; + // } + public static removeUser() { + if(Session.isLoggedIn()){ + localStorage.removeItem("user"); + COOKIE.deleteCookie(COOKIE.cookieName_id) + COOKIE.deleteCookie(COOKIE.cookieName_u); + } + } + public static getUser():User { + if(Session.isLoggedIn()){ + return JSON.parse(localStorage.getItem("user")); + }else{ + return null; + } + } + public static isLoggedIn(): boolean { + var loggedIn:boolean = false; + var user:User = null; + var cookie= COOKIE.getCookie(COOKIE.cookieName_u); + if( typeof localStorage !== 'undefined') { + if(localStorage.getItem("user")) { + user = JSON.parse(localStorage.getItem("user")); + if(user && (user.fullname != null || user.lastname !=null || user.firstname !=null)){ + + loggedIn = true; + }else if(cookie != null && this.getUserFromCookie()!= null){ + loggedIn = true + }else{ + loggedIn = false; + } + }else{ + if(cookie != null && this.getUserFromCookie()!= null){ + loggedIn = true + }else{ + loggedIn = false; + } + + } + }else{ + loggedIn = false; + } + return loggedIn; + } + public static getUserFromCookie():User{ + var cookie= COOKIE.getCookie(COOKIE.cookieName_u); + if(cookie != null){ + var user:User = MyJWT.parseUserInfo(cookie); + if( typeof localStorage !== 'undefined') { + localStorage.setItem("user", JSON.stringify(user)); + if(user && user.email){ + COOKIE.deleteCookie(COOKIE.cookieName_u); // delete cookie to avoid transfer through requests + return user; + }else{ + return null; + } + }else{ + return null; + } + }else{ + return null; + } + } + public static getUserJwt():string { + if(Session.isLoggedIn()){ + return Session.getUser().jwt; + }else{ + return null; + } + + } + public static getUserEmail():string { + if(Session.isLoggedIn()){ + return Session.getUser().email; + }else{ + return null; + } + + } + public static getCurrentUrl():string { + if( typeof localStorage !== 'undefined') { + return localStorage.getItem("url"); + } + return ""; + + } + public static setCurrentUrl(url:string) { + if( typeof localStorage !== 'undefined') { + localStorage.setItem("url", url); + } + } + public static getCurrentParameters():any { + if( typeof localStorage !== 'undefined') { + var params = localStorage.getItem("params"); + console.log(params); + var object = null; + if(params.split("&").length > 0){ + object = {}; + } + for(var i=0; i 1)? params:""); + } + } + public static isAdminUser():boolean { + var isAdmin = false; + if(Session.isLoggedIn()){ + var claimRoles = ["urn:mace:openminted.eu:aai.openminted.eu:group:OpenAIRE+Curator+-+Claim","urn:mace:openminted.eu:aai.openminted.eu:group:OpenAIRE+Portal+Administrator"] + for (var i = 0; i < claimRoles.length; i++) { + if ((Session.getUser().role).indexOf(claimRoles[i]) > -1) { + isAdmin = true; + break; + } + } + // console.log("Is admin:"+ isAdmin) + return (isAdmin); + } + // console.log("Is admin:"+ isAdmin) + return (isAdmin); + } + public static isRegisteredUser():boolean { + var isRegisteredUser = false; + if(Session.isLoggedIn()){ + var claimRoles = ["urn:mace:openminted.eu:aai.openminted.eu:group:Registered+User"]; + for (var i = 0; i < claimRoles.length; i++) { + if ((Session.getUser().role).indexOf(claimRoles[i]) > -1) { + isRegisteredUser = true; + break; + } + } + // console.log("Is isRegisteredUser:"+ isRegisteredUser) + return (isRegisteredUser); + } + // console.log("Is isRegisteredUser:"+ isRegisteredUser) + return (isRegisteredUser); + } + public static isUserValid() { + if(Session.isLoggedIn()){ + var expires = Session.getUser().expirationDate; + var now = new Date().getTime() / 1000; + // console.log(" is still valid ? "+(now +0 < expires) +" Remaining:"+ (expires - (now+0))+ " now is:"+now + "expires at:"+expires); + return now +0 < expires; + } + return false; + } + public static isValidAndRemove() { + if(Session.isLoggedIn()){ + if(!Session.isUserValid()){ + Session.removeUser(); + return false; + }else{ + return true; + } + }else{ + return false; + } + } + +} +export class MyJWT{ + private static validateJWTFormat(data){ + if(data != null && (data.indexOf(".") !=-1 && data.split('.').length == 3)){ + return true; + } + return false; + } + private static getPayload(data){ + var payload = data.split('.')[1]; + return StringUtils.b64DecodeUnicode(payload); + } + public static parseUserInfo(data: any): User { + if(this.validateJWTFormat(data)){ + var info = JSON.parse(this.getPayload(data)); + }else{ + return null; + } + var user: User = new User(); + + user.firstname = (StringUtils.URIDecode((info.firstname && info.firstname!="")?info.firstname:"")).replace("+"," "); + user.lastname = (StringUtils.URIDecode((info.lastname && info.lastname!="")?info.lastname:"")).replace("+"," "); + user.email = info.email; + // user.id = info.userId; + user.fullname = (StringUtils.URIDecode((info.fullname && info.fullname!="")?info.fullname:"")).replace("+"," "); + if(user.fullname == ""){ + if(user.firstname != ""){ + user.fullname += user.firstname; + } + if(user.lastname !=""){ + user.fullname += user.lastname; + } + if(user.fullname == ""){ //it is still empty set a default + user.fullname = "Anonymous user"; + } + } + if(info.role && info.role != ""){ + user.role =JSON.parse( StringUtils.URIDecode(info.role)); + }else{ + user.role =[]; + } + + // console.log("User Role is:"); + // console.log(user.role) + user.jwt = data; + user.expirationDate = info.exp; + localStorage.setItem("user", JSON.stringify(user)); + console.log(user) + return user; + } + +} + export class COOKIE{ + public static cookieName_u:string="XCsrfToken"; + public static cookieName_id:string="AccessToken"; + + public static getCookie(name: string) : string { + if(typeof document == 'undefined'){ + return null; + } + let ca: Array = document.cookie.split(';'); + let caLen: number = ca.length; + let cookieName = `${name}=`; + let c: string; + + for (let i: number = 0; i < caLen; i += 1) { + c = ca[i].replace(/^\s+/g, ''); + if (c.indexOf(cookieName) == 0) { + return c.substring(cookieName.length, c.length); + } + } + return null; + } + public static deleteCookie(name) { + this.setCookie(name, '', -1); + } + public static setCookie(name: string, value: string, expireDays: number, path: string = '/') { + let d:Date = new Date(); + d.setTime(d.getTime() + expireDays * 24 * 60 * 60 * 1000); + let expires:string = `expires=${d.toUTCString()}`; + // let cpath:string = path ? `; path=${path}` : ''; + document.cookie = name+'='+value+'; path='+path+'; domain='+OpenaireProperties.getCookieDomain()+';'; + } +} diff --git a/login/utils/logoutOpenaire.service.ts b/login/utils/logoutOpenaire.service.ts new file mode 100644 index 00000000..b000789f --- /dev/null +++ b/login/utils/logoutOpenaire.service.ts @@ -0,0 +1,19 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; + import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import 'rxjs/add/operator/do'; +@Injectable() +export class LogoutOpenaireService { + + constructor(private http: Http ) {} + + logout():any { + console.info("Logout openaire"); + //let url = OpenaireProperties. getSearchAPIURLLast() + 'publications/' +id+"?format=json"; + let url = OpenaireProperties.getLogoutOpenaireURL(); + + return this.http.get(url).do(request => console.info("Log out?" )); + } + +} diff --git a/reload/reload-routing.module.ts b/reload/reload-routing.module.ts new file mode 100644 index 00000000..f304da05 --- /dev/null +++ b/reload/reload-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import{ReloadComponent} from './reload.component'; +import {FreeGuard} from'../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: ReloadComponent, canActivate: [FreeGuard], canDeactivate: [PreviousRouteRecorder] } + + ]) + ] +}) +export class ReloadRoutingModule { } diff --git a/reload/reload.component.ts b/reload/reload.component.ts new file mode 100644 index 00000000..50338a48 --- /dev/null +++ b/reload/reload.component.ts @@ -0,0 +1,55 @@ +import {Component, Input, Output, EventEmitter, ViewChild, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; +import {Location} from '@angular/common'; + +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {ErrorCodes} from '../utils/properties/openaireProperties'; +import {RouterHelper} from '../utils/routerHelper.class'; +import {Session} from '../login/utils/helper.class'; + +@Component({ + selector: 'reload', + template: ` +
    +
    +
    +
    + Go to initial page.... +
    +
    +
    +
    + ` +}) +export class ReloadComponent { + + constructor (private element: ElementRef, + private route: ActivatedRoute, + private _router: Router, + private location: Location + ) { + + } + + public ngOnInit() { + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + var url = Session.getCurrentUrl(); + if(url && url != null && url != ""){ + Session.setCurrentUrl(""); + var paramsObject = Session.getCurrentParameters(); + Session.setCurrentParameters(""); + if(paramsObject && paramsObject != null){ + this._router.navigate([url],{ queryParams: paramsObject}); + }else{ + this._router.navigate([url]); + } + }else{ + this._router.navigate(['/']); + + } + } + +} diff --git a/reload/reload.module.ts b/reload/reload.module.ts new file mode 100644 index 00000000..2b7e8469 --- /dev/null +++ b/reload/reload.module.ts @@ -0,0 +1,29 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import{ReloadRoutingModule } from './reload-routing.module'; +import{ReloadComponent} from './reload.component'; + + + import {FreeGuard} from'../login/freeGuard.guard'; +import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, + ReloadRoutingModule + + ], + declarations: [ + ReloadComponent + ], + providers:[ + FreeGuard, PreviousRouteRecorder + ], + exports: [ + ReloadComponent + ] +}) +export class ReloadModule { } diff --git a/searchPages/advanced/advancedSearchDataProviders.component.ts b/searchPages/advanced/advancedSearchDataProviders.component.ts new file mode 100644 index 00000000..6ccd0768 --- /dev/null +++ b/searchPages/advanced/advancedSearchDataProviders.component.ts @@ -0,0 +1,153 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router, ActivatedRoute} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {AdvancedSearchPageComponent} from '../searchUtils/advancedSearchPage.component'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + + + +@Component({ + selector: 'advanced-search-dataprovider', + template: ` + + + + ` + }) + +export class AdvancedSearchDataProvidersComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public searchFields:SearchFields = new SearchFields(); + + public fieldIds: string[] = this.searchFields.DATASOURCE_ADVANCED_FIELDS; + public fieldIdsMap= this.searchFields.DATASOURCE_FIELDS; + public selectedFields:AdvancedField[] = []; + + @ViewChild (AdvancedSearchPageComponent) searchPage : AdvancedSearchPageComponent ; + public resourcesQuery = "(oaftype exact datasource)"; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + constructor (private route: ActivatedRoute, private _searchDataProvidersService: SearchDataprovidersService ) { + this.results =[]; + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.baseUrl = OpenaireProperties.searchLinkToAdvancedDataProviders; + console.info("Con -base url:"+this.searchUtils.baseUrl ); + + } + ngOnInit() { + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + let page = (params['page']=== undefined)?0:+params['page']; + this.searchUtils.page = ( page < 1 ) ? 1 : page; + this.searchPage.fieldIds = this.fieldIds; + this.selectedFields =[]; + this.searchPage.selectedFields = this.selectedFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.getSelectedFiltersFromUrl(params); + this.getResults(this.searchPage.createQueryParameters(), this.searchUtils.page, this.searchUtils.size); + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + public getResults(parameters:string, page: number, size: number){ + if(parameters!= null && parameters != '' ) { + this.csvParams ="&type=datasources&query=( "+this.resourcesQuery + "and (" + parameters + "))"; + }else{ + this.csvParams ="&type=datasources&query="+this.resourcesQuery; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + console.info("Advanced Search for Content Providers: Execute search query "+parameters); + this._searchDataProvidersService.advancedSearchDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("Adv Search Content Providers total="+this.searchUtils.totalResults); + this.results = data[1]; + this.searchPage.updateBaseUrlWithParameters(); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + console.info("error"); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = errorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.NOT_AVAILABLE; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this.getResults(parameters, this.searchUtils.page,this.searchUtils.size); + console.info("queryChanged: Execute search query "+parameters); + + } + + +} diff --git a/searchPages/advanced/advancedSearchDataProviders.module.ts b/searchPages/advanced/advancedSearchDataProviders.module.ts new file mode 100644 index 00000000..333e386b --- /dev/null +++ b/searchPages/advanced/advancedSearchDataProviders.module.ts @@ -0,0 +1,28 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{AdvancedSearchDataProvidersComponent} from './advancedSearchDataProviders.component'; + + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; + import {AdvancedSearchPageModule} from '../searchUtils/advancedSearchPage.module'; + import {FreeGuard} from'../../login/freeGuard.guard'; + import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + AdvancedSearchPageModule + + ], + declarations: [ + AdvancedSearchDataProvidersComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + AdvancedSearchDataProvidersComponent + ] +}) +export class AdvancedSearchDataProvidersModule { } diff --git a/searchPages/advanced/advancedSearchDatasets.component.ts b/searchPages/advanced/advancedSearchDatasets.component.ts new file mode 100644 index 00000000..e31af8ad --- /dev/null +++ b/searchPages/advanced/advancedSearchDatasets.component.ts @@ -0,0 +1,161 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router, ActivatedRoute} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +import {SearchDatasetsService} from '../../services/searchDatasets.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {AdvancedSearchPageComponent} from '../searchUtils/advancedSearchPage.component'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + + +@Component({ + selector: 'advanced-search-datasets', + template: ` + + + + ` + }) + +export class AdvancedSearchDatasetsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public searchFields:SearchFields = new SearchFields(); + + public fieldIds: string[] = this.searchFields.RESULT_ADVANCED_FIELDS; + public fieldIdsMap= this.searchFields.RESULT_FIELDS; + public selectedFields:AdvancedField[] = []; + + @ViewChild (AdvancedSearchPageComponent) searchPage : AdvancedSearchPageComponent ; + public resourcesQuery = "( (oaftype exact result) and (resulttypeid exact dataset) )"; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + constructor (private route: ActivatedRoute, private _searchDatasetsService: SearchDatasetsService ) { + this.results =[]; + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.baseUrl = OpenaireProperties.searchLinkToAdvancedDatasets; + + + + } + ngOnInit() { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + let page = (params['page']=== undefined)?1:+params['page']; + this.searchUtils.page = ( page <= 0 ) ? 1 : page; + this.searchPage.fieldIds = this.fieldIds; + this.selectedFields =[]; + this.searchPage.selectedFields = this.selectedFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.getSelectedFiltersFromUrl(params); + this.getResults(this.searchPage.createQueryParameters(), this.searchUtils.page, this.searchUtils.size); + + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + public getResults(parameters:string, page: number, size: number){ + if(parameters!= null && parameters != '' ) { + this.csvParams ="&type=datasets&query=( "+this.resourcesQuery + "and (" + parameters + "))"; + }else{ + this.csvParams ="&type=datasets&query="+this.resourcesQuery; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + console.info("Advanced Search for Research Data: Execute search query "+parameters); + this._searchDatasetsService.advancedSearchDatasets(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data total="+this.searchUtils.totalResults); + this.results = data[1]; + this.searchPage.updateBaseUrlWithParameters(); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + console.info("error"); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = errorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.NOT_AVAILABLE; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this.getResults(parameters, this.searchUtils.page,this.searchUtils.size); + console.info("queryChanged: Execute search query "+parameters); + + } + + +} diff --git a/searchPages/advanced/advancedSearchDatasets.module.ts b/searchPages/advanced/advancedSearchDatasets.module.ts new file mode 100644 index 00000000..d56cc181 --- /dev/null +++ b/searchPages/advanced/advancedSearchDatasets.module.ts @@ -0,0 +1,28 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{AdvancedSearchDatasetsComponent} from './advancedSearchDatasets.component'; + + +import {DatasetsServiceModule} from '../../services/datasetsService.module'; + import {AdvancedSearchPageModule} from '../searchUtils/advancedSearchPage.module'; + import {FreeGuard} from'../../login/freeGuard.guard'; + import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DatasetsServiceModule, + AdvancedSearchPageModule + + ], + declarations: [ + AdvancedSearchDatasetsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + AdvancedSearchDatasetsComponent + ] +}) +export class AdvancedSearchDatasetsModule { } diff --git a/searchPages/advanced/advancedSearchOrganizations.component.ts b/searchPages/advanced/advancedSearchOrganizations.component.ts new file mode 100644 index 00000000..320c1bd9 --- /dev/null +++ b/searchPages/advanced/advancedSearchOrganizations.component.ts @@ -0,0 +1,161 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router, ActivatedRoute} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +import {SearchOrganizationsService} from '../../services/searchOrganizations.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {AdvancedSearchPageComponent} from '../searchUtils/advancedSearchPage.component'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + + +@Component({ + selector: 'advanced-search-organizations', + template: ` + + + + ` + }) + +export class AdvancedSearchOrganizationsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public searchFields:SearchFields = new SearchFields(); + + public fieldIds: string[] = this.searchFields.ORGANIZATION_ADVANCED_FIELDS; + public fieldIdsMap = this.searchFields.ORGANIZATION_FIELDS; + public selectedFields:AdvancedField[] = []; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (AdvancedSearchPageComponent) searchPage : AdvancedSearchPageComponent ; + +public resourcesQuery = "(oaftype exact organization)"; + constructor (private route: ActivatedRoute, private _searchOrganizationsService: SearchOrganizationsService ) { + this.results =[]; + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.baseUrl = OpenaireProperties.searchLinkToAdvancedOrganizations; + + + + } + ngOnInit() { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + let page = (params['page']=== undefined)?1:+params['page']; + this.searchUtils.page = ( page <= 0 ) ? 1 : page; + this.searchPage.fieldIds = this.fieldIds; + this.selectedFields =[]; + this.searchPage.selectedFields = this.selectedFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.getSelectedFiltersFromUrl(params); + this.getResults(this.searchPage.createQueryParameters(), this.searchUtils.page, this.searchUtils.size); + + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + public getResults(parameters:string, page: number, size: number){ + if(parameters!= null && parameters != '' ) { + this.csvParams ="&type=organizations&query=( "+this.resourcesQuery + "and (" + parameters + "))"; + }else{ + this.csvParams ="&type=organizations&query="+this.resourcesQuery; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + console.info("Advanced Search for Organizations: Execute search query "+parameters); + this._searchOrganizationsService.advancedSearchOrganizations(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Organizations total="+this.searchUtils.totalResults); + this.results = data[1]; + this.searchPage.updateBaseUrlWithParameters(); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + console.info("error"); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = errorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.NOT_AVAILABLE; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this.getResults(parameters, this.searchUtils.page,this.searchUtils.size); + console.info("queryChanged: Execute search query "+parameters); + + } + + +} diff --git a/searchPages/advanced/advancedSearchOrganizations.module.ts b/searchPages/advanced/advancedSearchOrganizations.module.ts new file mode 100644 index 00000000..2ce5a6fa --- /dev/null +++ b/searchPages/advanced/advancedSearchOrganizations.module.ts @@ -0,0 +1,28 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{AdvancedSearchOrganizationsComponent} from './advancedSearchOrganizations.component'; + + +import {OrganizationsServiceModule} from '../../services/organizationsService.module'; + import {AdvancedSearchPageModule} from '../searchUtils/advancedSearchPage.module'; + import {FreeGuard} from'../../login/freeGuard.guard'; + import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + OrganizationsServiceModule, + AdvancedSearchPageModule + + ], + declarations: [ + AdvancedSearchOrganizationsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + AdvancedSearchOrganizationsComponent + ] +}) +export class AdvancedSearchOrganizationsModule { } diff --git a/searchPages/advanced/advancedSearchProjects.component.ts b/searchPages/advanced/advancedSearchProjects.component.ts new file mode 100644 index 00000000..769d6f5d --- /dev/null +++ b/searchPages/advanced/advancedSearchProjects.component.ts @@ -0,0 +1,162 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router, ActivatedRoute} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +import {SearchProjectsService} from '../../services/searchProjects.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {AdvancedSearchPageComponent} from '../searchUtils/advancedSearchPage.component'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'advanced-search-projects', + template: ` + + + + ` + }) + +export class AdvancedSearchProjectsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public searchFields:SearchFields = new SearchFields(); + + public fieldIds: string[] = this.searchFields.PROJECT_ADVANCED_FIELDS; + public fieldIdsMap = this.searchFields.PROJECT_FIELDS; + public selectedFields:AdvancedField[] = []; + + @ViewChild (AdvancedSearchPageComponent) searchPage : AdvancedSearchPageComponent ; + public resourcesQuery = "(oaftype exact project)"; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + constructor (private route: ActivatedRoute, private _searchProjectsService: SearchProjectsService ) { + + this.results =[]; + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.baseUrl = OpenaireProperties.searchLinkToAdvancedProjects; + + + + } + ngOnInit() { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + let page = (params['page']=== undefined)?1:+params['page']; + this.searchUtils.page = ( page <= 0 ) ? 1 : page; + this.searchPage.fieldIds = this.fieldIds; + this.selectedFields =[]; + this.searchPage.selectedFields = this.selectedFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.getSelectedFiltersFromUrl(params); + this.getResults(this.searchPage.createQueryParameters(), this.searchUtils.page, this.searchUtils.size); + + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + public getResults(parameters:string, page: number, size: number){ + if(parameters!= null && parameters != '' ) { + this.csvParams ="&type=projects&query=( "+this.resourcesQuery + "and (" + parameters + "))"; + }else{ + this.csvParams ="&type=projects&query="+this.resourcesQuery; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + console.info("Advanced Search for Publications: Execute search query "+parameters); + this._searchProjectsService.advancedSearchProjects(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("Advanced Search for Projects total="+this.searchUtils.totalResults); + this.results = data[1]; + this.searchPage.updateBaseUrlWithParameters(); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + console.info("error"); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = errorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.NOT_AVAILABLE; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this.getResults(parameters, this.searchUtils.page,this.searchUtils.size); + console.info("queryChanged: Execute search query "+parameters); + + } + + +} diff --git a/searchPages/advanced/advancedSearchProjects.module.ts b/searchPages/advanced/advancedSearchProjects.module.ts new file mode 100644 index 00000000..1239745e --- /dev/null +++ b/searchPages/advanced/advancedSearchProjects.module.ts @@ -0,0 +1,28 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{AdvancedSearchProjectsComponent} from './advancedSearchProjects.component'; + + +import {ProjectsServiceModule} from '../../services/projectsService.module'; + import {AdvancedSearchPageModule} from '../searchUtils/advancedSearchPage.module'; + import {FreeGuard} from'../../login/freeGuard.guard'; + import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + ProjectsServiceModule, + AdvancedSearchPageModule + + ], + declarations: [ + AdvancedSearchProjectsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + AdvancedSearchProjectsComponent + ] +}) +export class AdvancedSearchProjectsModule { } diff --git a/searchPages/advanced/advancedSearchPublications.component.ts b/searchPages/advanced/advancedSearchPublications.component.ts new file mode 100644 index 00000000..eec08478 --- /dev/null +++ b/searchPages/advanced/advancedSearchPublications.component.ts @@ -0,0 +1,160 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router, ActivatedRoute} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +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, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + + +@Component({ + selector: 'advanced-search-publications', + template: ` + + + ` + }) + +export class AdvancedSearchPublicationsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public searchFields:SearchFields = new SearchFields(); + + public fieldIds: string[] = this.searchFields.RESULT_ADVANCED_FIELDS; + public fieldIdsMap= this.searchFields.RESULT_FIELDS; + public selectedFields:AdvancedField[] = []; + public resourcesQuery = "((oaftype exact result) and (resulttypeid exact publication))"; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (AdvancedSearchPageComponent) searchPage : AdvancedSearchPageComponent ; + + + constructor (private route: ActivatedRoute, private _searchPublicationsService: SearchPublicationsService ) { + + this.results =[]; + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.baseUrl = OpenaireProperties.searchLinkToAdvancedPublications; + + + + } + ngOnInit() { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + let page = (params['page']=== undefined)?1:+params['page']; + this.searchUtils.page = ( page <= 0 ) ? 1 : page; + this.searchPage.fieldIds = this.fieldIds; + this.selectedFields =[]; + this.searchPage.selectedFields = this.selectedFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + + this.searchPage.getSelectedFiltersFromUrl(params); + this.getResults(this.searchPage.createQueryParameters(), this.searchUtils.page, this.searchUtils.size); + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + public getResults(parameters:string, page: number, size: number){ + if(parameters!= null && parameters != '' ) { + this.csvParams ="&type=publications&query=("+this.resourcesQuery +" and (" + parameters + "))"; + }else{ + this.csvParams ="&type=publications&query="+this.resourcesQuery; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + console.info("Advanced Search for Publications: Execute search query "+parameters); + this._searchPublicationsService.advancedSearchPublications(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("searchPubl total="+this.searchUtils.totalResults); + this.results = data[1]; + this.searchPage.updateBaseUrlWithParameters(); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + console.info("error"); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.NOT_AVAILABLE; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this.getResults(parameters, this.searchUtils.page,this.searchUtils.size); + console.info("queryChanged: Execute search query "+parameters); + + } + + +} diff --git a/searchPages/advanced/advancedSearchPublications.module.ts b/searchPages/advanced/advancedSearchPublications.module.ts new file mode 100644 index 00000000..225234bc --- /dev/null +++ b/searchPages/advanced/advancedSearchPublications.module.ts @@ -0,0 +1,28 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{AdvancedSearchPublicationsComponent} from './advancedSearchPublications.component'; + + +import {PublicationsServiceModule} from '../../services/publicationsService.module'; + import {AdvancedSearchPageModule} from '../searchUtils/advancedSearchPage.module'; + import {FreeGuard} from'../../login/freeGuard.guard'; + import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + PublicationsServiceModule, + AdvancedSearchPageModule + + ], + declarations: [ + AdvancedSearchPublicationsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + AdvancedSearchPublicationsComponent + ] +}) +export class AdvancedSearchPublicationsModule { } diff --git a/searchPages/advanced/advancedSearchSoftware.component.ts b/searchPages/advanced/advancedSearchSoftware.component.ts new file mode 100644 index 00000000..5de0eda7 --- /dev/null +++ b/searchPages/advanced/advancedSearchSoftware.component.ts @@ -0,0 +1,161 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Router, ActivatedRoute} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +import {SearchSoftwareService} from '../../services/searchSoftware.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {AdvancedSearchPageComponent} from '../searchUtils/advancedSearchPage.component'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + + +@Component({ + selector: 'advanced-search-software', + template: ` + + + + ` + }) + +export class AdvancedSearchSoftwareComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public searchFields:SearchFields = new SearchFields(); + + public fieldIds: string[] = this.searchFields.RESULT_ADVANCED_FIELDS; + public fieldIdsMap= this.searchFields.RESULT_FIELDS; + public selectedFields:AdvancedField[] = []; + + @ViewChild (AdvancedSearchPageComponent) searchPage : AdvancedSearchPageComponent ; + public resourcesQuery = "( (oaftype exact result) and (resulttypeid exact software) )"; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + constructor (private route: ActivatedRoute, private _searchSoftwareService: SearchSoftwareService ) { + this.results =[]; + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.baseUrl = OpenaireProperties.searchLinkToAdvancedSoftware; + + + + } + ngOnInit() { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + let page = (params['page']=== undefined)?1:+params['page']; + this.searchUtils.page = ( page <= 0 ) ? 1 : page; + this.searchPage.fieldIds = this.fieldIds; + this.selectedFields =[]; + this.searchPage.selectedFields = this.selectedFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.getSelectedFiltersFromUrl(params); + this.getResults(this.searchPage.createQueryParameters(), this.searchUtils.page, this.searchUtils.size); + + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + } + sub: any; + public getResults(parameters:string, page: number, size: number){ + if(parameters!= null && parameters != '' ) { + this.csvParams ="&type=software&query=( "+this.resourcesQuery + "and (" + parameters + "))"; + }else{ + this.csvParams ="&type=software&query="+this.resourcesQuery; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + console.info("Advanced Search for Software: Execute search query "+parameters); + this._searchSoftwareService.advancedSearchSoftware(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software total="+this.searchUtils.totalResults); + this.results = data[1]; + this.searchPage.updateBaseUrlWithParameters(); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + console.info("error"); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = errorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.NOT_AVAILABLE; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this.getResults(parameters, this.searchUtils.page,this.searchUtils.size); + console.info("queryChanged: Execute search query "+parameters); + + } + + +} diff --git a/searchPages/advanced/advancedSearchSoftware.module.ts b/searchPages/advanced/advancedSearchSoftware.module.ts new file mode 100644 index 00000000..01f95b15 --- /dev/null +++ b/searchPages/advanced/advancedSearchSoftware.module.ts @@ -0,0 +1,28 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{AdvancedSearchSoftwareComponent} from './advancedSearchSoftware.component'; + + +import {SoftwareServiceModule} from '../../services/softwareService.module'; + import {AdvancedSearchPageModule} from '../searchUtils/advancedSearchPage.module'; + import {FreeGuard} from'../../login/freeGuard.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + SoftwareServiceModule, + AdvancedSearchPageModule + + ], + declarations: [ + AdvancedSearchSoftwareComponent + ], + providers:[FreeGuard + ], + exports: [ + AdvancedSearchSoftwareComponent + ] +}) +export class AdvancedSearchSoftwareModule { } diff --git a/searchPages/dataProviders/compatibleDataProviders.component.ts b/searchPages/dataProviders/compatibleDataProviders.component.ts new file mode 100644 index 00000000..a069f62d --- /dev/null +++ b/searchPages/dataProviders/compatibleDataProviders.component.ts @@ -0,0 +1,184 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Location} from '@angular/common'; +import { ActivatedRoute} from '@angular/router'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-content-providers', + template: ` + + + + + ` + +}) +export class SearchCompatibleDataprovidersComponent { + private errorCodes: ErrorCodes; + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.COMPATIBLE_DATAPROVIDER_FIELDS; + public fieldIdsMap= this.searchFields.DATASOURCE_FIELDS; + public _prefixQueryFields: {field:string,opName:string,opValue:string,values:string[]}[] =[{field:"compatibility",opName:"cm",opValue:"not", values:["UNKNOWN","hostedBy","notCompatible"]},{field:"type",opName:"tp",opValue:"not",values: ["other"]}]; + // ["entityregistry","entityregistry::projects","entityregistry::repositories"]}]; + public _prefixQuery: string = ""; + + public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public resourcesQuery = '&query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other) not(datasourcetypeuiid exact "pubsrepository::journal") not(datasourcetypeuiid exact "aggregator::pubsrepository::journals"))'; + public csvParams: string; + public disableForms: boolean = false; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.baseUrl = OpenaireProperties.getLinkToSearchCompatibleDataProviders(); + for(var i = 0; i < this._prefixQueryFields.length; i++ ){ + for(var j =0; j < this._prefixQueryFields[i].values.length; j++){ + this._prefixQuery+="&" + this._prefixQueryFields[i].field + "=" + + this._prefixQueryFields[i].values[j] + "&" + + this._prefixQueryFields[i].opName + "=" + this._prefixQueryFields[i].opValue; + } + } + this._prefixQuery+="&"; + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.sub = this.route.queryParams.subscribe(params => { + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + this.filters = this.createFilters(); + var queryParameters = this.searchPage.getIndexQueryParametersFromUrl(params); + console.info("|"+queryParameters+"|"); + this._getResults(queryParameters, false, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } } + private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters+this.resourcesQuery+"&type=datasources"; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchDataprovidersService.searchCompatibleDataproviders(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Content Providers: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + var parameters = $event.index; + console.info("queryChanged: Execute search query "+parameters); + + this._getResults(parameters, false, this.searchUtils.page, this.searchUtils.size); + } + private createFilters():Filter[] { + var filter_names=["Type","Compatibility Level"]; + var filter_ids=["datasourcetypeuiid","datasourcecompatibilityname"]; + var searchFields = new SearchFields(); + var filter_original_ids = searchFields.COMPATIBLE_DATAPROVIDER_FIELDS; + var value_names=[ + /*[ + "Institutional Publication Repository","Thematic Publication Repository", "Other Publication Repository", + "Institutional Repositories Aggregators", + "Thematic Repositories Aggregators", "Other Repositories Aggregators", + "Data Repositories", "Data Repositories Aggregators", "Journals", "Journals Aggregators", "CRIS Systems", "Publication Catalogues"], + */ + [ + "Institutional Repository", "Thematic Repository", "Publication Repository", + "Institutional Repository Aggregator", + "Thematic Repositories Aggregators", "Publication Repository Aggregator", + "Data Repository", "Data Repository Aggregator", "CRIS Systems", "Publication Catalogue"], + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var value_original_ids=[ + ["pubsrepository::institutional","pubsrepository::thematic", "pubsrepository::unknown", "aggregator::pubsrepository::institutional","aggregator::pubsrepository::thematic","aggregator::pubsrepository::unknown", + "datarepository::unknown", "aggregator::datarepository", "cris", "pubscatalogue::unknown"], + //["driver","openaire2.0", "driver-openaire2.0", "openaire3.0","openaire2.0_data"] + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + var filters: Filter[] =[]; + for(var i =0 ; i < filter_names.length;i++){ + var values:Value[] = []; + for(var j =0 ; j < value_names[i].length;j++){ + var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false} + values.push(value); + } + var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or' }; + filters.push(filter); + } + return filters; + } +} diff --git a/searchPages/dataProviders/compatibleDataProviders.module.ts b/searchPages/dataProviders/compatibleDataProviders.module.ts new file mode 100644 index 00000000..62d0c525 --- /dev/null +++ b/searchPages/dataProviders/compatibleDataProviders.module.ts @@ -0,0 +1,27 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchCompatibleDataprovidersComponent} from './compatibleDataProviders.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + SearchFormModule, SearchResultsModule, SearchPageModule + + ], + declarations: [ + SearchCompatibleDataprovidersComponent + ], + exports: [ + SearchCompatibleDataprovidersComponent + ] +}) +export class CompatibleDataProvidersModule { } diff --git a/searchPages/dataProviders/compatibleDataProvidersTable.component.ts b/searchPages/dataProviders/compatibleDataProvidersTable.component.ts new file mode 100644 index 00000000..4f07d603 --- /dev/null +++ b/searchPages/dataProviders/compatibleDataProvidersTable.component.ts @@ -0,0 +1,195 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import {Location} from '@angular/common'; +import { ActivatedRoute} from '@angular/router'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageTableViewComponent } from '../searchUtils/searchPageTableView.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-content-providers-table', + template: ` + + + + ` + +}) +export class SearchCompatibleDataprovidersTableComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.COMPATIBLE_DATAPROVIDER_FIELDS; + + /*public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public csvParams: string; + public resourcesQuery = "&query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other))";*/ + + public disableForms: boolean = false; + + @ViewChild (SearchPageTableViewComponent) searchPage : SearchPageTableViewComponent ; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.baseUrl = OpenaireProperties.getLinkToSearchCompatibleDataProvidersTable(); + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.sub = this.route.queryParams.subscribe(params => { + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + //this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + this.filters = this.createFilters(); + this.searchPage.getParametersFromUrl(params); + this._getResults(); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } } + private _getResults(){ + //this.csvParams = this.resourcesQuery+"&type=datasources"; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + let size: number = 0; + this.subResults = this._searchDataprovidersService.searchCompatibleDataprovidersTable().subscribe( + data => { + size = data; + if(size > 0) { + this.subResults = this._searchDataprovidersService.searchCompatibleDataproviders("", null, 1, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Content Providers [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + this.searchPage.checkSelectedFilters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + this.disableForms = false; + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + this.disableForms = false; + + } + ); + } else { + this.searchPage.checkSelectedFilters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.NONE; + this.disableForms = false; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + + } + private setFilters(){ + //TODO set filters from + } + + private createFilters():Filter[] { + var filter_names=["Type","Compatibility Level"]; + var filter_ids=["datasourcetypeuiid","datasourcecompatibilityname"]; + var searchFields = new SearchFields(); + var filter_original_ids = searchFields.COMPATIBLE_DATAPROVIDER_FIELDS; + var value_names=[ + /*[ + "Institutional Publication Repository","Thematic Publication Repository", "Other Publication Repository", + "Institutional Repositories Aggregators", + "Thematic Repositories Aggregators", "Other Repositories Aggregators", + "Data Repositories", "Data Repositories Aggregators", "Journals", "Journals Aggregators", "CRIS Systems", "Publication Catalogues"], + */ + [ + "Institutional Repository", "Thematic Repository", "Publication Repository", + "Institutional Repository Aggregator", + "Thematic Repositories Aggregators", "Publication Repository Aggregator", + "Data Repository", "Data Repository Aggregator", "CRIS Systems", "Publication Catalogue"], + + + + + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var value_original_ids=[ + ["pubsrepository::institutional","pubsrepository::thematic", "pubsrepository::unknown", "aggregator::pubsrepository::institutional","aggregator::pubsrepository::thematic","aggregator::pubsrepository::unknown", + "datarepository::unknown", "aggregator::datarepository", "cris", "pubscatalogue::unknown"], + //["driver","openaire2.0", "driver-openaire2.0", "openaire3.0","openaire2.0_data"] + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + var filters: Filter[] =[]; + for(var i =0 ; i < filter_names.length;i++){ + var values:Value[] = []; + for(var j =0 ; j < value_names[i].length;j++){ + var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false} + values.push(value); + } + var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or' }; + filters.push(filter); + } + return filters; + } +} diff --git a/searchPages/dataProviders/compatibleDataProvidersTable.module.ts b/searchPages/dataProviders/compatibleDataProvidersTable.module.ts new file mode 100644 index 00000000..95c36833 --- /dev/null +++ b/searchPages/dataProviders/compatibleDataProvidersTable.module.ts @@ -0,0 +1,26 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchCompatibleDataprovidersTableComponent} from './compatibleDataProvidersTable.component'; + + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +import {SearchPageTableViewModule} from '../searchUtils/searchPageTableView.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + SearchFormModule, SearchPageTableViewModule + + ], + declarations: [ + SearchCompatibleDataprovidersTableComponent + ], + exports: [ + SearchCompatibleDataprovidersTableComponent + ] +}) +export class CompatibleDataProvidersTableModule { } diff --git a/searchPages/dataProviders/entityRegistries.component.ts b/searchPages/dataProviders/entityRegistries.component.ts new file mode 100644 index 00000000..8339ac42 --- /dev/null +++ b/searchPages/dataProviders/entityRegistries.component.ts @@ -0,0 +1,176 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-entity-registries', + template: ` + + + + + ` + +}) +export class SearchEntityRegistriesComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.ENTITY_REGISTRIES_FIELDS; + public fieldIdsMap= this.searchFields.DATASOURCE_FIELDS; + public _prefixQueryFields: {field:string,opName:string,opValue:string,values:string[]}[] =[ + {field:"type",opName:"tp",opValue:"and",values: ["other"]}]; + // ["entityregistry","entityregistry::projects","entityregistry::repositories"]}]; + public _prefixQuery: string = ""; + + public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public disableForms: boolean = false; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + public resourcesQuery = "&query=((oaftype exact datasource) and(datasourcetypeuiid = other))"; + public csvParams: string; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.baseUrl = OpenaireProperties.getLinkToSearchEntityRegistries(); + for(var i = 0; i < this._prefixQueryFields.length; i++ ){ + for(var j =0; j < this._prefixQueryFields[i].values.length; j++){ + this._prefixQuery+="&" + this._prefixQueryFields[i].field + "=" + + this._prefixQueryFields[i].values[j] + "&" + + this._prefixQueryFields[i].opName + "=" + this._prefixQueryFields[i].opValue; + } + } + this._prefixQuery+="&"; + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.sub = this.route.queryParams.subscribe(params => { + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + this.filters = this.createFilters(); + + var queryParameters = this.searchPage.getIndexQueryParametersFromUrl(params); + this._getResults(queryParameters, false, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } } + private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters+this.resourcesQuery+"&type=datasources"; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchDataprovidersService.searchEntityRegistries(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Entity Registries: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + var parameters = $event.index; + console.info("queryChanged: Execute search query "+parameters); + this._getResults(parameters, false, this.searchUtils.page, this.searchUtils.size); + } + private createFilters():Filter[] { + var filter_names=["Type","Compatibility Level"]; + var filter_ids=["datasourcetypename","datasourcecompatibilityname"]; + var searchFields = new SearchFields(); + var filter_original_ids = searchFields.ENTITY_REGISTRIES_FIELDS; + var value_names=[ + ["Funder","Registry of repositories","Scholarly Comm. Infrastructure","Registry","Information Space","Web Source"], + + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var value_original_ids=[ + ["Funder database","Registry of repositories","Scholarly Comm. Infrastructure","Registry","Information Space","Web Source"], + //["entityregistry::projects","entityregistry::repositories","scholarcomminfra","entityregistry","infospace","websource"], + //["driver","openaire2.0", "driver-openaire2.0", "openaire3.0","openaire2.0_data"] + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var filters: Filter[] =[]; + for(var i =0 ; i < filter_names.length;i++){ + var values:Value[] = []; + for(var j =0 ; j < value_names[i].length;j++){ + var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false} + values.push(value); + } + var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or' }; + filters.push(filter); + } + return filters; + } +} diff --git a/searchPages/dataProviders/entityRegistries.module.ts b/searchPages/dataProviders/entityRegistries.module.ts new file mode 100644 index 00000000..4b5dcf6e --- /dev/null +++ b/searchPages/dataProviders/entityRegistries.module.ts @@ -0,0 +1,25 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchEntityRegistriesComponent} from './entityRegistries.component'; +import {SearchResultsModule } from '../searchUtils/searchResults.module'; +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + SearchFormModule, SearchResultsModule, SearchPageModule + + ], + declarations: [ + SearchEntityRegistriesComponent + ], + exports: [ + SearchEntityRegistriesComponent + ] +}) +export class EntityRegistriesModule { } diff --git a/searchPages/dataProviders/entityRegistriesTable.component.ts b/searchPages/dataProviders/entityRegistriesTable.component.ts new file mode 100644 index 00000000..dd016bb9 --- /dev/null +++ b/searchPages/dataProviders/entityRegistriesTable.component.ts @@ -0,0 +1,204 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageTableViewComponent } from '../searchUtils/searchPageTableView.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-entity-registries-table', + template: ` + + + + + ` + +}) +export class SearchEntityRegistriesTableComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.ENTITY_REGISTRIES_FIELDS; + public disableForms: boolean = false; + + @ViewChild (SearchPageTableViewComponent) searchPage : SearchPageTableViewComponent ; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.sub = this.route.queryParams.subscribe(params => { + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + //this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + this.filters = this.createFilters(); + + this.searchPage.getParametersFromUrl(params); + this._getResults("", false, this.searchUtils.page); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } } + private _getResults(parameters:string,refine:boolean, page: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + let size: number = 0; + this.subResults = this._searchDataprovidersService.searchEntityRegistriesTable().subscribe( + data => { + size = data; + if(size > 0) { + this.subResults = this._searchDataprovidersService.searchEntityRegistries("",null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Entity Registries [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + this.searchPage.checkSelectedFilters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + this.disableForms = false; + + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + this.disableForms = false; + + } + ); + } else { + this.searchPage.checkSelectedFilters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.NONE; + this.disableForms = false; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); +/* + this.subResults = this._searchDataprovidersService.searchEntityRegistries(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Entity Registries: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = errorCodes.ERROR; + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); +*/ + } + private setFilters(){ + //TODO set filters from + } + + + private createFilters():Filter[] { + var filter_names=["Type","Compatibility Level"]; + var filter_ids=["datasourcetypename","datasourcecompatibilityname"]; + var searchFields = new SearchFields(); + var filter_original_ids = searchFields.ENTITY_REGISTRIES_FIELDS; + var value_names=[ + ["Funder database","Registry of repositories","Scholarly Comm. Infrastructure","Registry","Information Space","Web Source"], + + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var value_original_ids=[ + ["Funder database","Registry of repositories","Scholarly Comm. Infrastructure","Registry","Information Space","Web Source"], + //["entityregistry::projects","entityregistry::repositories","scholarcomminfra","entityregistry","infospace","websource"], + //["driver","openaire2.0", "driver-openaire2.0", "openaire3.0","openaire2.0_data"] + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var filters: Filter[] =[]; + for(var i =0 ; i < filter_names.length;i++){ + var values:Value[] = []; + for(var j =0 ; j < value_names[i].length;j++){ + var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false} + values.push(value); + } + var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or' }; + filters.push(filter); + } + return filters; + } +} diff --git a/searchPages/dataProviders/entityRegistriesTable.module.ts b/searchPages/dataProviders/entityRegistriesTable.module.ts new file mode 100644 index 00000000..42ef101a --- /dev/null +++ b/searchPages/dataProviders/entityRegistriesTable.module.ts @@ -0,0 +1,24 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchEntityRegistriesTableComponent} from './entityRegistriesTable.component'; +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +import {SearchPageTableViewModule} from '../searchUtils/searchPageTableView.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + SearchFormModule, SearchPageTableViewModule + + ], + declarations: [ + SearchEntityRegistriesTableComponent + ], + exports: [ + SearchEntityRegistriesTableComponent + ] +}) +export class EntityRegistriesTableModule { } diff --git a/searchPages/dataProviders/journals.component.ts b/searchPages/dataProviders/journals.component.ts new file mode 100644 index 00000000..7d7c527d --- /dev/null +++ b/searchPages/dataProviders/journals.component.ts @@ -0,0 +1,181 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-journals', + template: ` + + + + ` + +}) +export class SearchJournalsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.JOURNAL_FIELDS; + public fieldIdsMap= this.searchFields.DATASOURCE_FIELDS; + public _prefixQueryFields: {field:string,opName:string,opValue:string,values:string[]}[] =[{field:"compatibility",opName:"cm",opValue:"not", values:["UNKNOWN","hostedBy","notCompatible"]},{field:"type",opName:"tp",opValue:"not",values: ["other"]}]; + // ["entityregistry","entityregistry::projects","entityregistry::repositories"]}]; + public _prefixQuery: string = ""; + + public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public resourcesQuery = '&query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) and (datasourcetypeuiid exact "pubsrepository::journal" or datasourcetypeuiid exact "aggregator::pubsrepository::journals" ))'; + //"&query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other))"; + public csvParams: string; + public disableForms: boolean = false; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.baseUrl = OpenaireProperties.getLinkToSearchJournals(); + for(var i = 0; i < this._prefixQueryFields.length; i++ ){ + for(var j =0; j < this._prefixQueryFields[i].values.length; j++){ + this._prefixQuery+="&" + this._prefixQueryFields[i].field + "=" + + this._prefixQueryFields[i].values[j] + "&" + + this._prefixQueryFields[i].opName + "=" + this._prefixQueryFields[i].opValue; + } + } + this._prefixQuery+="&"; + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.sub = this.route.queryParams.subscribe(params => { + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + this.filters = this.createFilters(); + var queryParameters = this.searchPage.getIndexQueryParametersFromUrl(params); + console.info("|"+queryParameters+"|"); + this._getResults(queryParameters, false, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } } + private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters+this.resourcesQuery+"&type=datasources"; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchDataprovidersService.searchJournals(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Journals: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); + } + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + var parameters = $event.index; + console.info("queryChanged: Execute search query "+parameters); + + this._getResults(parameters, false, this.searchUtils.page, this.searchUtils.size); + } + private createFilters():Filter[] { + var filter_names=["Type","Compatibility Level"]; + var filter_ids=["datasourcetypeuiid","datasourcecompatibilityname"]; + var searchFields = new SearchFields(); + var filter_original_ids = searchFields.JOURNAL_FIELDS; + var value_names=[ + /*[ + "Institutional Publication Repository","Thematic Publication Repository", "Other Publication Repository", + "Institutional Repositories Aggregators", + "Thematic Repositories Aggregators", "Other Repositories Aggregators", + "Data Repositories", "Data Repositories Aggregators", "Journals", "Journals Aggregators", "CRIS Systems", "Publication Catalogues"], + */ + ["Journal", "Journal Aggregator\/Publisher"], + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var value_original_ids=[ + ["pubsrepository::journal", "aggregator::pubsrepository::journals"], + //["driver","openaire2.0", "driver-openaire2.0", "openaire3.0","openaire2.0_data"] + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + var filters: Filter[] =[]; + for(var i =0 ; i < filter_names.length;i++){ + var values:Value[] = []; + for(var j =0 ; j < value_names[i].length;j++){ + var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false} + values.push(value); + } + var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or' }; + filters.push(filter); + } + return filters; + } +} diff --git a/searchPages/dataProviders/journals.module.ts b/searchPages/dataProviders/journals.module.ts new file mode 100644 index 00000000..296987e5 --- /dev/null +++ b/searchPages/dataProviders/journals.module.ts @@ -0,0 +1,27 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchJournalsComponent} from './journals.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + SearchFormModule, SearchResultsModule, SearchPageModule + + ], + declarations: [ + SearchJournalsComponent + ], + exports: [ + SearchJournalsComponent + ] +}) +export class JournalsModule { } diff --git a/searchPages/dataProviders/journalsTable.component.ts b/searchPages/dataProviders/journalsTable.component.ts new file mode 100644 index 00000000..1c4bb74e --- /dev/null +++ b/searchPages/dataProviders/journalsTable.component.ts @@ -0,0 +1,191 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageTableViewComponent } from '../searchUtils/searchPageTableView.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-journals-table', + template: ` + + + + ` + +}) +export class SearchJournalsTableComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.JOURNAL_FIELDS; + + /*public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public csvParams: string; + public resourcesQuery = "&query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other))";*/ + + public disableForms: boolean = false; + + @ViewChild (SearchPageTableViewComponent) searchPage : SearchPageTableViewComponent ; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.baseUrl = OpenaireProperties.getLinkToSearchJournalsTable(); + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.sub = this.route.queryParams.subscribe(params => { + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + //this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + this.filters = this.createFilters(); + this.searchPage.getParametersFromUrl(params); + this._getResults(); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } } + private _getResults(){ + //this.csvParams = this.resourcesQuery+"&type=datasources"; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + let size: number = 0; + this.subResults = this._searchDataprovidersService.searchJournalsTable().subscribe( + data => { + size = data; + if(size > 0) { + this.subResults = this._searchDataprovidersService.searchJournals("", null, 1, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Journals [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + this.searchPage.checkSelectedFilters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + this.disableForms = false; + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + this.disableForms = false; + + } + ); + } else { + this.searchPage.checkSelectedFilters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.NONE; + this.disableForms = false; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + + } + private setFilters(){ + //TODO set filters from + } + + private createFilters():Filter[] { + var filter_names=["Type","Compatibility Level"]; + var filter_ids=["datasourcetypeuiid","datasourcecompatibilityname"]; + var searchFields = new SearchFields(); + var filter_original_ids = searchFields.JOURNAL_FIELDS; + var value_names=[ + /*[ + "Institutional Publication Repository","Thematic Publication Repository", "Other Publication Repository", + "Institutional Repositories Aggregators", + "Thematic Repositories Aggregators", "Other Repositories Aggregators", + "Data Repositories", "Data Repositories Aggregators", "Journals", "Journals Aggregators", "CRIS Systems", "Publication Catalogues"], + */ + ["Journal", "Journal Aggregator\/Publisher"], + + + + + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + + var value_original_ids=[ + ["pubsrepository::journal", "aggregator::pubsrepository::journals"], + //["driver","openaire2.0", "driver-openaire2.0", "openaire3.0","openaire2.0_data"] + ["OpenAIRE Basic (DRIVER OA)","OpenAIRE 2.0 (EC funding)", "OpenAIRE 2.0+ (DRIVER OA, EC funding)", "OpenAIRE 3.0 (OA, funding)","OpenAIRE Data (funded, referenced datasets)"]]; + var filters: Filter[] =[]; + for(var i =0 ; i < filter_names.length;i++){ + var values:Value[] = []; + for(var j =0 ; j < value_names[i].length;j++){ + var value:Value = {name: value_names[i][j], id: value_original_ids[i][j], number:j, selected:false} + values.push(value); + } + var filter:Filter = {title: filter_names[i], filterId: filter_ids[i], originalFilterId: filter_original_ids[i], values : values, countSelectedValues:0, "filterOperator": 'or' }; + filters.push(filter); + } + return filters; + } +} diff --git a/searchPages/dataProviders/journalsTable.module.ts b/searchPages/dataProviders/journalsTable.module.ts new file mode 100644 index 00000000..2a50de8a --- /dev/null +++ b/searchPages/dataProviders/journalsTable.module.ts @@ -0,0 +1,25 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchJournalsTableComponent} from './journalsTable.component'; + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +import {SearchPageTableViewModule} from '../searchUtils/searchPageTableView.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + DataProvidersServiceModule, + SearchFormModule, SearchPageTableViewModule + + ], + declarations: [ + SearchJournalsTableComponent + ], + exports: [ + SearchJournalsTableComponent + ] +}) +export class JournalsTableModule { } diff --git a/searchPages/find/mainSearch.module.ts b/searchPages/find/mainSearch.module.ts new file mode 100644 index 00000000..ae96d666 --- /dev/null +++ b/searchPages/find/mainSearch.module.ts @@ -0,0 +1,40 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +// import{MainSearchRoutingModule} from './mainSearch-routing.module'; +import{SearchComponent} from './search.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import {SoftwareServiceModule} from '../../services/softwareService.module'; +import {ProjectsServiceModule} from '../../services/projectsService.module'; +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {OrganizationsServiceModule} from '../../services/organizationsService.module'; +import {BrowseEntitiesModule} from '../searchUtils/browseEntities.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; + +import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, + DataProvidersServiceModule, DatasetsServiceModule, SoftwareServiceModule, ProjectsServiceModule, + PublicationsServiceModule, OrganizationsServiceModule, + BrowseEntitiesModule, SearchFormModule, SearchResultsModule, PiwikServiceModule + + ], + declarations: [ + SearchComponent + ], + providers:[ + //FreeGuard, PreviousRouteRecorder + ], + exports: [ + SearchComponent + ] +}) +export class MainSearchModule { } diff --git a/searchPages/find/search.component.html b/searchPages/find/search.component.html new file mode 100644 index 00000000..16d936d9 --- /dev/null +++ b/searchPages/find/search.component.html @@ -0,0 +1,241 @@ + + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + + + + +
    + +
    +
    +
    +
    diff --git a/searchPages/find/search.component.ts b/searchPages/find/search.component.ts new file mode 100644 index 00000000..7e713828 --- /dev/null +++ b/searchPages/find/search.component.ts @@ -0,0 +1,400 @@ +import {Component, Input, Output, EventEmitter, ViewChild, ChangeDetectionStrategy, ViewEncapsulation} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ActivatedRoute, Router} from '@angular/router'; +import {Location} from '@angular/common'; + +import { Meta, MetaDefinition} from '../../../angular2-meta'; + +import { FetchPublications } from '../../utils/fetchEntitiesClasses/fetchPublications.class'; +import { FetchDataproviders } from '../../utils/fetchEntitiesClasses/fetchDataproviders.class'; +import { FetchProjects } from '../../utils/fetchEntitiesClasses/fetchProjects.class'; +import { FetchDatasets } from '../../utils/fetchEntitiesClasses/fetchDatasets.class'; +import { FetchSoftware } from '../../utils/fetchEntitiesClasses/fetchSoftware.class'; +import { FetchOrganizations } from '../../utils/fetchEntitiesClasses/fetchOrganizations.class'; + +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchProjectsService} from '../../services/searchProjects.service'; +import {SearchDatasetsService} from '../../services/searchDatasets.service'; +import {SearchSoftwareService} from '../../services/searchSoftware.service'; +import {SearchOrganizationsService} from '../../services/searchOrganizations.service'; + +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {ErrorCodes} from '../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../utils/routerHelper.class'; +import {RefineFieldResultsService} from '../../services/refineFieldResults.service'; +import {PiwikService} from '../../utils/piwik/piwik.service'; +import { ConfigurationService } from '../../utils/configuration/configuration.service'; + +@Component({ + changeDetection: ChangeDetectionStrategy.Default, + encapsulation: ViewEncapsulation.Emulated, + selector: 'search-find', + templateUrl: 'search.component.html' +}) +export class SearchComponent { + public sub: any; piwiksub: any; + public reloadPublications: boolean; + public reloadDatasets: boolean; + public reloadSoftware: boolean; + public reloadProjects: boolean; + public reloadDataproviders: boolean; + public reloadOrganizations: boolean; + + + public pageTitle = "Search in OpenAIRE" + public keyword:string = ""; + public publications:string[]; + public datasets:string[]; + public software:string[]; + public projectsTab:string[]; + public dataproviders:string[]; + public organizations:string[]; + + public activeTab = "publications"; + public linkToSearchPublications = ""; + public linkToSearchProjects = ""; + public linkToSearchDataproviders = ""; + public linkToSearchDatasets = ""; + public linkToSearchSoftware = ""; + public linkToSearchOrganizations = ""; + + public fetchPublications : FetchPublications; + public fetchDataproviders : FetchDataproviders; + public fetchProjects : FetchProjects; + public fetchDatasets: FetchDatasets; + public fetchSoftware: FetchSoftware; + public fetchOrganizations: FetchOrganizations; + + public searchFields:SearchFields = new SearchFields(); + public errorCodes:ErrorCodes = new ErrorCodes(); + public routerHelper:RouterHelper = new RouterHelper(); + + public publicationsSize:any = null; + public datasetsSize:any = null; + public softwareSize:any = null; + public fundersSize:any = null; + public projectsSize:any = null; + public datasourcesSize:any = null; + showPublications:boolean= false; + showDatasets:boolean= false; + showSoftware:boolean=false; + showProjects:boolean= false; + showDataProviders:boolean= false; + showOrganizations:boolean= false; +public subPub;public subData;public subProjects;public subOrg; public subDataPr; + constructor ( private route: ActivatedRoute, + private _router: Router, + private _searchPublicationsService: SearchPublicationsService, + private _searchDataprovidersService: SearchDataprovidersService, + private _searchProjectsService: SearchProjectsService, + private _searchDatasetsService: SearchDatasetsService, + private _searchSoftwareService: SearchSoftwareService, + private _searchOrganizationsService: SearchOrganizationsService, + private _refineFieldResultsService:RefineFieldResultsService, + private location: Location, private _meta: Meta,private _piwikService:PiwikService, + private config: ConfigurationService ) { + this.fetchPublications = new FetchPublications(this._searchPublicationsService); + this.fetchDataproviders = new FetchDataproviders(this._searchDataprovidersService); + this.fetchProjects = new FetchProjects(this._searchProjectsService); + this.fetchDatasets = new FetchDatasets( this._searchDatasetsService); + this.fetchSoftware = new FetchSoftware(this._searchSoftwareService); + this.fetchOrganizations = new FetchOrganizations( this._searchOrganizationsService); + + var description = "open access, research, scientific publication, European Commission, EC, FP7, ERC, Horizon 2020, H2020, search, projects "; + + var title = "OpenAIRE | Search publications, research data, projects... | OpenAIRE"; + + var url = OpenaireProperties.getBaseLink()+this._router.url; + this._meta.setTitle(title); + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + this._meta.updateProperty("og:title", title); + this._meta.updateProperty("og:url", url); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView("OpenAIRE |Search publications, research data, projects...").subscribe(); + + } + + + + } + + public ngOnInit() { + const entityOne = this.config.isEntityEnabled("publication"); + const entityTwo = this.config.isEntityEnabled("dataset"); + const entityThree = this.config.isEntityEnabled("project"); + const entityFour = this.config.isEntityEnabled("organization"); + const entityFive = this.config.isEntityEnabled("datasource"); + const entitySix = this.config.isEntityEnabled("software"); + const example = Observable.zip(entityOne,entityTwo,entityThree,entityFour,entityFive,entitySix); + +//wait until all observables have emitted a value then emit all as an array + this.sub = this.route.queryParams.subscribe(params => { + const subscribe = example.subscribe(data => { + this.showPublications = data[0]; + this.showDatasets = data[1]; + this.showProjects = data[2]; + this.showOrganizations = data[3]; + this.showDataProviders = data[4]; + this.showSoftware = data[5]; + console.log(data) + this.keyword = (params['keyword'])?params['keyword']:""; + if(this.keyword !=null && this.keyword.length > 0){ + this.reloadTabs(); + //if showPublications == false will set another entity as the first + if(this.showPublications){ + this.activeTab = "publications"; + this.searchPublications(); + }else if(this.showDatasets){ + this.activeTab = "research data"; + this.searchDatasets(); + }else if(this.showSoftware){ + this.activeTab = "software"; + this.searchSoftware(); + }else if(this.showProjects){ + this.activeTab = "projects"; + this.searchProjects(); + }else if(this.showDataProviders){ + this.activeTab = "content providers"; + this.searchDataProviders(); + }else if(this.showOrganizations){ + this.activeTab = "organizations"; + this.searchOrganizations(); + } + this.count(); + } + }); + }); + + } + public ngOnDestroy() { + this.sub.unsubscribe(); + if(this.piwiksub){ + this.piwiksub.unsubscribe(); +} + if(this.keyword !=null && this.keyword.length > 0){ + if(this.subPub){ + this.subPub.unsubscribe(); + } + if(this.subData){ + this.subData.unsubscribe(); + } + if(this.subProjects){ + this.subProjects.unsubscribe(); + } + if(this.subOrg){ + this.subOrg.unsubscribe(); + } + if(this.subDataPr){ + this.subDataPr.unsubscribe(); + } + + } + } + public searchPublications() { + this.activeTab = "publications"; + if( this.reloadPublications && + this.fetchPublications.searchUtils.status != this.errorCodes.NONE && + this.fetchPublications.searchUtils.status != this.errorCodes.ERROR) { + this.reloadPublications = false; + this.fetchPublications.getResultsByKeyword(this.keyword, 1, 10); + this.linkToSearchPublications = OpenaireProperties.getLinkToSearchPublications();// + "?keyword=" + this.keyword; + } + } + public searchDatasets() { + this.activeTab = "research data"; + if(this.reloadDatasets && + this.fetchDatasets.searchUtils.status != this.errorCodes.NONE && + this.fetchDatasets.searchUtils.status != this.errorCodes.ERROR) { + this.reloadDatasets = false; + this.fetchDatasets.getResultsByKeyword(this.keyword, 1, 10); + this.linkToSearchDatasets = OpenaireProperties.getLinkToSearchDatasets();// + "?keyword=" + this.keyword; + } + } + public searchSoftware() { + this.activeTab = "software"; + if(this.reloadSoftware && + ( this.fetchSoftware.searchUtils.status == this.errorCodes.LOADING || + this.fetchSoftware.searchUtils.status == this.errorCodes.DONE )) { + this.reloadSoftware = false; + this.fetchSoftware.getResultsByKeyword(this.keyword, 1, 10); + this.linkToSearchSoftware = OpenaireProperties.getLinkToSearchSoftware();// + "?keyword=" + this.keyword; + } + } + public searchProjects() { + this.activeTab = "projects"; + if(this.reloadProjects && + this.fetchProjects.searchUtils.status != this.errorCodes.NONE && + this.fetchProjects.searchUtils.status != this.errorCodes.ERROR) { + this.reloadProjects = false; + this.fetchProjects.getResultsByKeyword(this.keyword, 1, 10); + this.linkToSearchProjects = OpenaireProperties.getLinkToSearchProjects();// + "?keyword=" + this.keyword; + } + } + public searchDataProviders() { + this.activeTab = "content providers"; + if( this.reloadDataproviders && + this.fetchDataproviders.searchUtils.status != this.errorCodes.NONE && + this.fetchDataproviders.searchUtils.status != this.errorCodes.ERROR) { + this.reloadDataproviders = false; + this.fetchDataproviders.getResultsByKeyword(this.keyword, 1, 10); + this.linkToSearchDataproviders = OpenaireProperties.getLinkToSearchDataProviders();// + "?keyword=" + this.keyword; + } + } + public searchOrganizations() { + this.activeTab = "organizations"; + if( this.reloadOrganizations && + this.fetchOrganizations.searchUtils.status != this.errorCodes.NONE && + this.fetchOrganizations.searchUtils.status != this.errorCodes.ERROR) { + this.reloadOrganizations = false; + this.fetchOrganizations.getResultsByKeyword(this.keyword, 1, 10); + this.linkToSearchOrganizations = OpenaireProperties.getLinkToSearchOrganizations();// + "?keyword=" + this.keyword; + } + } + + + public keywordChanged($event){ + + this.keyword = $event.value; + console.info("Search Find: search with keyword \"" + this.keyword + "\"" ); + this.location.go(location.pathname,"?keyword=" + this.keyword); + this.reloadTabs(); + if(this.activeTab == "publications") { + this.searchPublications(); + } + if(this.activeTab == "projects") { + this.searchProjects(); + } + if(this.activeTab == "content providers") { + this.searchDataProviders(); + } + if(this.activeTab == "research data") { + this.searchDatasets(); + } + if(this.activeTab == "software") { + this.searchSoftware(); + } + if(this.activeTab == "organizations") { + this.searchOrganizations(); + } + + this.count(); + } + + private count() { + if(this.activeTab != "publications" && this.showPublications){ + this.fetchPublications.searchUtils.status = this.errorCodes.LOADING; + this.fetchPublications.results = []; + this.subPub = this._searchPublicationsService.numOfSearchPublications(this.keyword).subscribe( + data => { + console.log("Count results: "+data); + this.fetchPublications.searchUtils.totalResults = data; + this.fetchPublications.searchUtils.status = this.errorCodes.DONE; + if(this.fetchPublications.searchUtils.totalResults == 0) { + this.fetchPublications.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + this.fetchPublications.searchUtils.status = this.errorCodes.ERROR; + } + ); + } + if(this.activeTab != "research data" && this.showDatasets){ + this.fetchDatasets.searchUtils.status = this.errorCodes.LOADING; + this.fetchDatasets.results = []; + this.subData = this._searchDatasetsService.numOfSearchDatasets(this.keyword).subscribe( + data => { + this.fetchDatasets.searchUtils.totalResults = data; + this.fetchDatasets.searchUtils.status = this.errorCodes.DONE; + if(this.fetchDatasets.searchUtils.totalResults == 0) { + this.fetchDatasets.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + this.fetchDatasets.searchUtils.status = this.errorCodes.ERROR; + } + ); + } + if(this.activeTab != "software" && this.showSoftware){ + this.fetchSoftware.searchUtils.status = this.errorCodes.LOADING; + this.fetchSoftware.results = []; + this.subData = this._searchSoftwareService.numOfSearchSoftware(this.keyword).subscribe( + data => { + this.fetchSoftware.searchUtils.totalResults = data; + this.fetchSoftware.searchUtils.status = this.errorCodes.DONE; + if(this.fetchSoftware.searchUtils.totalResults == 0) { + this.fetchSoftware.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + if(err.status == '404') { + this.fetchSoftware.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.fetchSoftware.searchUtils.status = this.errorCodes.ERROR; + } else { + this.fetchSoftware.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + //this.fetchSoftware.searchUtils.status = this.errorCodes.ERROR; + } + ); + } + if(this.activeTab != "projects" && this.showProjects){ + this.fetchProjects.searchUtils.status = this.errorCodes.LOADING; + this.fetchProjects.results = []; + this.subProjects = this._searchProjectsService.numOfSearchProjects(this.keyword).subscribe( + data => { + this.fetchProjects.searchUtils.totalResults = data; + this.fetchProjects.searchUtils.status = this.errorCodes.DONE; + if(this.fetchProjects.searchUtils.totalResults == 0) { + this.fetchProjects.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + this.fetchProjects.searchUtils.status = this.errorCodes.ERROR; + } + ); + } + if(this.activeTab != "content providers" && this.showDataProviders){ + this.fetchDataproviders.results = []; + this.fetchDataproviders.getNumForSearch(this.keyword); + } + if(this.activeTab != "organizations" && this.showOrganizations){ + this.fetchOrganizations.searchUtils.status = this.errorCodes.LOADING; + this.fetchOrganizations.results = []; + this.subOrg = this._searchOrganizationsService.numOfSearchOrganizations(this.keyword).subscribe( + data => { + this.fetchOrganizations.searchUtils.totalResults = data; + this.fetchOrganizations.searchUtils.status = this.errorCodes.DONE; + if(this.fetchOrganizations.searchUtils.totalResults == 0) { + this.fetchOrganizations.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + this.fetchOrganizations.searchUtils.status = this.errorCodes.ERROR; + + } + ); + } + + + } + + private reloadTabs() { + this.reloadPublications = true; + this.reloadDatasets = true; + this.reloadSoftware = true; + this.reloadProjects = true; + this.reloadDataproviders = true; + this.reloadOrganizations = true; + } + + + +} diff --git a/searchPages/searchUtils/advancedSearchForm.component.html b/searchPages/searchUtils/advancedSearchForm.component.html new file mode 100644 index 00000000..938ca3cd --- /dev/null +++ b/searchPages/searchUtils/advancedSearchForm.component.html @@ -0,0 +1,56 @@ + +
    + + + + + + + + + + + + + + + + +
    Search for: + + + + + + + + Yes
    +
    + + No
    +
    +
    + + + + + + + + +
    +
    + +
    + +
    diff --git a/searchPages/searchUtils/advancedSearchForm.component.ts b/searchPages/searchUtils/advancedSearchForm.component.ts new file mode 100644 index 00000000..3700ab57 --- /dev/null +++ b/searchPages/searchUtils/advancedSearchForm.component.ts @@ -0,0 +1,95 @@ +import {Component, Input, Output, EventEmitter, ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import { Subject } from 'rxjs/Subject'; + +import {AdvancedField, OPERATOR} from '../searchUtils/searchHelperClasses.class'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {Dates} from '../../utils/string-utils.class'; + +@Component({ + selector: 'advanced-search-form', + templateUrl: 'advancedSearchForm.component.html' +}) +export class AdvancedSearchFormComponent { + @Input() entityType; + @Input() fieldIds: string[]; + @Input() fieldIdsMap; + @Input() selectedFields:AdvancedField[]; + @Input() isDisabled: boolean = false; + + @Output() queryChange = new EventEmitter(); + newFieldId:string; + newFieldName:string; + fieldList:{[id:string]:any[]} = {}; + public searchFields:SearchFields = new SearchFields(); + + public operators: [{name:string, id:string}] = this.searchFields.ADVANCED_SEARCH_OPERATORS; + constructor () { + } + + ngOnInit() { + for(var i = 0; i < this.fieldIds.length; i++){ + this.fieldList[this.fieldIds[i]]=[]; + } + this.newFieldId = this.fieldIds[0]; + this.newFieldName = this.fieldIdsMap[this.newFieldId].name; + } + + queryChanged() { + this.queryChange.emit({ + // selectedFields: this.selectedFields, + // selectedQuantifiers: this.selectedQuantifiers, + // keywords: this.keywords + }); + } + + addField() { + this.newFieldId = this.fieldIds[0]; + var type = this.fieldIdsMap[this.newFieldId].type; + if(type == "boolean"){ + this.selectedFields.push(new AdvancedField(this.newFieldId,this.fieldIdsMap[this.newFieldId].param, this.fieldIdsMap[this.newFieldId].name, type, "true", "and")); + }else{ + this.selectedFields.push(new AdvancedField(this.newFieldId, this.fieldIdsMap[this.newFieldId].param,this.fieldIdsMap[this.newFieldId].name, type, "", "and")); + } + + } + + removeField(index: number) { + this.selectedFields.splice(index, 1); + + } + + fieldOperatorChanged(index: number, operatorId: string, operatorName: string) { + this.selectedFields[index].operatorId = operatorId; + this.selectedFields[index].operatorName = operatorName; + } + validateDate(index: number, value: string){ + this.selectedFields[index].valid = Dates.isValidYear(value); + } + + fieldIdsChanged(index: number, fieldId:string ) { + console.log("Field index::"+index + " " + this.selectedFields[index].id + " function id:" +fieldId); + + var id= this.fieldIds[0]; + this.selectedFields[index].name = this.fieldIdsMap[id].name; + this.selectedFields[index].type = this.fieldIdsMap[id].type; + this.selectedFields[index].value = ""; + this.selectedFields[index].param = this.fieldIdsMap[id].param; + + var id =fieldId;//this.selectedFields[index].id; + this.selectedFields[index].name = this.fieldIdsMap[id].name; + this.selectedFields[index].type = this.fieldIdsMap[id].type; + this.selectedFields[index].value = ""; + this.selectedFields[index].param = this.fieldIdsMap[id].param; + if(this.fieldIdsMap[id].type == "boolean"){ + this.selectedFields[index].value = "true"; + } + } + valueChanged($event,index:number){ + this.selectedFields[index].value = $event.value; + } + listUpdated($event,fieldId:number){ + this.fieldList[fieldId] = $event.value; + } + +} diff --git a/searchPages/searchUtils/advancedSearchForm.module.ts b/searchPages/searchUtils/advancedSearchForm.module.ts new file mode 100644 index 00000000..1ee2f437 --- /dev/null +++ b/searchPages/searchUtils/advancedSearchForm.module.ts @@ -0,0 +1,26 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{AdvancedSearchFormComponent} from './advancedSearchForm.component'; +import {EntitiesAutocompleteModule} from '../../utils/entitiesAutoComplete/entitiesAutoComplete.module'; +import {StaticAutocompleteModule} from '../../utils/staticAutoComplete/staticAutoComplete.module'; +import {DateFilterModule} from './dateFilter.module'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule, EntitiesAutocompleteModule, StaticAutocompleteModule, DateFilterModule + ], + declarations: [ + AdvancedSearchFormComponent, +], + + providers:[ + ], + exports: [ + AdvancedSearchFormComponent + + ] +}) +export class AdvancedSearchFormModule { } diff --git a/searchPages/searchUtils/advancedSearchPage.component.html b/searchPages/searchUtils/advancedSearchPage.component.html new file mode 100644 index 00000000..bea9e58f --- /dev/null +++ b/searchPages/searchUtils/advancedSearchPage.component.html @@ -0,0 +1,61 @@ +
    +
    +
    +
    +
    + {{pageTitle}} +
    +
    + Simple search + + + + +
    + +
    +
    + +
    +
    + +
    + + + +
    + + +
    +
    + +
    + + + +
    +
    + + +
    + +
    + +
    + +
    +
    +
    + +
    +
    +
    diff --git a/searchPages/searchUtils/advancedSearchPage.component.ts b/searchPages/searchUtils/advancedSearchPage.component.ts new file mode 100644 index 00000000..3ffeffb2 --- /dev/null +++ b/searchPages/searchUtils/advancedSearchPage.component.ts @@ -0,0 +1,254 @@ +import {Component, Input, ViewChild, Output, EventEmitter} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {Location} from '@angular/common'; +import { Router} from '@angular/router'; +import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchUtilsClass} from './searchUtils.class'; +import {ModalLoading} from '../../utils/modal/loading.component'; +import {StringUtils, Dates} from '../../utils/string-utils.class'; +import { Meta} from '../../../angular2-meta'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'advanced-search-page', + templateUrl: 'advancedSearchPage.component.html' +}) +export class AdvancedSearchPageComponent { + @Input() pageTitle = ""; + @Input() results = []; + @Input() type; + @Input() entityType; + @Input() searchUtils:SearchUtilsClass = new SearchUtilsClass(); + @Input() fieldIds: string[]; + @Input() fieldIdsMap;//:{ [key:string]:{ name:string, operator:string, type:string, indexField:string, equalityOperator:string }} ; + @Input() selectedFields:AdvancedField[]; + @Input() simpleSearchUrl: string; + @ViewChild (ModalLoading) loading : ModalLoading ; + @Input() csvParams: string; + @Input() csvPath: string; + @Input() simpleSearchLink: string = ""; + @Input() disableForms:boolean = false; + @Input() loadPaging: boolean = true; + @Input() oldTotalResults: number = 0; + + piwiksub: any; + public parameterNames:string[] =[]; + public parameterValues:string[] =[]; + + public baseURLWithParameters:string = ''; + + @Output() queryChange = new EventEmitter(); + constructor (private location: Location, private _meta: Meta, private _piwikService:PiwikService, private router: Router) { + } + + ngOnInit() { + this.updateTitle("Advanced search "+this.pageTitle); + this.updateDescription("Openaire, search, repositories, open access, type, content provider, funder, project, "+ this.pageTitle); + if(typeof window !== 'undefined') { + this.updateUrl(OpenaireProperties.getBaseLink()+location.pathname); + } + + this.searchUtils.baseUrl = "/" + this.searchUtils.baseUrl; + this.updateBaseUrlWithParameters(); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.pageTitle).subscribe(); + } + } + + ngOnDestroy() { + if(this.piwiksub){ + this.piwiksub.unsubscribe(); +} + } + updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + public getSelectedFiltersFromUrl(params){ + for(var i=0; i< this.fieldIds.length ; i++){ + + var fieldId = this.fieldIds[i]; + var fieldparam = (this.fieldIdsMap[fieldId])?this.fieldIdsMap[fieldId].param:""; + if(!this.fieldIdsMap[fieldId]){ + + console.error("Field: "+fieldId +" not found in fieldIds map"); + } + + var operatorId = this.getOperatorParameter(fieldparam); + if(params[fieldparam] != undefined && params[operatorId] != undefined) { + var values:string [] = StringUtils.URIDecode(params[fieldparam]).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); + var operators:string [] = (StringUtils.URIDecode(params[operatorId])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); + if(values.length == operators.length){ + for(var j=0; j< values.length ; j++){ + if(this.fieldIdsMap[fieldId].type == "date"){ + var value:string =StringUtils.unquote(values[j]); + var validDates:boolean = true; + var dateField:AdvancedField = new AdvancedField(fieldId,fieldparam,this.fieldIdsMap[fieldId].name,this.fieldIdsMap[fieldId].type,value,operators[j]) ; + if(value.indexOf("range") != -1){ + dateField.dateValue.type="range"; + if(value.length < 26 ){ + validDates =false; + }else{ + if(!Dates.isValidDate(value.substring(5,15)) || !Dates.isValidDate(value.substring(16,26))){ + validDates =false; + }else { + dateField.dateValue.from = Dates.getDateFromString(value.substring(5,15)); + dateField.dateValue.to = Dates.getDateFromString(value.substring(16,26)); + } + } + // "rangeYYYY-MM-DD:YYYY-MM-DD" + }else{ + dateField.dateValue.setDatesByType(value); + } + if(validDates){ + this.selectedFields.push(dateField); + } + + }else{ + this.selectedFields.push(new AdvancedField(fieldId,fieldparam,this.fieldIdsMap[fieldId].name,this.fieldIdsMap[fieldId].type,StringUtils.unquote(values[j]),operators[j]) ); + } + } + } + } + } + if(this.selectedFields.length == 0){ + this.selectedFields.push(new AdvancedField(this.fieldIds[0],fieldparam,this.fieldIdsMap[this.fieldIds[0]].name,this.fieldIdsMap[this.fieldIds[0]].type,"","and")); + } + } + private createUrlParameters(includePage:boolean){ + var params=""; + this.parameterNames.splice(0,this.parameterNames.length); + this.parameterValues.splice(0,this.parameterValues.length); + var fields: { [key:string]:{ values:string[], operators:string[] }}={}; + for(var i = 0; i< this.selectedFields.length; i++){ + if(this.fieldIdsMap[this.selectedFields[i].id] != undefined && (this.selectedFields[i].value.length > 0 || this.selectedFields[i].type == "date" )){ + 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 =[]; + } + if(this.selectedFields[i].type == "date"){ + if(this.selectedFields[i].dateValue.type == "range"){ + fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode("range"+Dates.getDateToString(this.selectedFields[i].dateValue.from)+":"+Dates.getDateToString(this.selectedFields[i].dateValue.to)))); + }else{ + fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode(this.selectedFields[i].dateValue.type))); + } + }else{ + fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode(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.fieldIdsMap[this.fieldIds[i]].param+"="+fields[this.fieldIds[i]].values.join()+ + "&"+this.getOperatorParameter(this.fieldIdsMap[this.fieldIds[i]].param)+"="+fields[this.fieldIds[i]].operators.join() + this.parameterNames.push(this.fieldIdsMap[this.fieldIds[i]].param); + this.parameterValues.push(fields[this.fieldIds[i]].values.join()); + this.parameterNames.push(this.getOperatorParameter(this.fieldIdsMap[this.fieldIds[i]].param)); + this.parameterValues.push(fields[this.fieldIds[i]].operators.join()); + } + } + if(includePage && this.searchUtils.page != 1){ + params += "&page="+this.searchUtils.page; + } + return '?'+params; + } + public createQueryParameters(){ + var params=""; + var countParams = 0; + for(var i = 0; i< this.selectedFields.length; i++){ + if(this.fieldIdsMap[this.selectedFields[i].id] != undefined && (this.selectedFields[i].value != "" ||this.selectedFields[i].type == "date")){ + console.log("createQueryParameters::"+this.selectedFields[i].type); + if(this.selectedFields[i].type == "date"){ + if(this.selectedFields[i].dateValue.type != "any"){ + params += (countParams == 0 ? "" : this.selectedFields[i].operatorId) + " " + this.selectedFields[i].id + this.fieldIdsMap[this.selectedFields[i].id].equalityOperator+ '"' + StringUtils.URIEncode(Dates.getDateToString(this.selectedFields[i].dateValue.from)) + " " + + StringUtils.URIEncode(Dates.getDateToString(this.selectedFields[i].dateValue.to)) + '"' + " "; + } + }else{ + if(this.selectedFields[i].id == "q"){ + var op = ""; + // if() + params += (countParams == 0 ? "" : this.selectedFields[i].operatorId) + " " + '"' + StringUtils.URIEncode(this.selectedFields[i].value) + '"' + " "; + }else if(countParams == 0 && this.selectedFields[i].operatorId == "not"){ + params += " "+ this.selectedFields[i].id + " <> "+'"' + StringUtils.URIEncode(this.selectedFields[i].value) +'"' + " "; + }else{ + params += (countParams == 0 ? "" : this.selectedFields[i].operatorId + " " ) + this.selectedFields[i].id + this.fieldIdsMap[this.selectedFields[i].id].equalityOperator+'"' + encodeURIComponent(this.selectedFields[i].value) +'"' + " "; + + } + } + countParams++; + } + } + + return params; + + } + clearFilters(){ + } + + goTo(page:number = 1){ + this.searchUtils.page = page; + var urlParameters = this.createUrlParameters(true); + var queryParameters = this.createQueryParameters(); + this.location.go(location.pathname,urlParameters); + this.queryChange.emit({ + value: queryParameters + }); + /* Code For Piwik*/ + if (typeof localStorage !== 'undefined') { + console.log("In PreviousRouteRecorder : "+this.router.url ); + localStorage.setItem('previousRoute', this.router.url); + } + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.pageTitle).subscribe(); + } + /* End Piwik Code */ + } + + queryChanged($event) { + + this.goTo(1); + } + pageChanged($event) { + this.searchUtils.page = +$event.value; + this.goTo(this.searchUtils.page); + } + /* + * Update the url with proper parameters. This is used as base url in Paging Component + */ + public updateBaseUrlWithParameters(){ + this.baseURLWithParameters = this.searchUtils.baseUrl + this.createUrlParameters(false); + } + getOperatorParameter(parameter:string):string{ + if(parameter.length > 2){ + return parameter.substring(0,2); + }else if(parameter == "q"){ + return "op"; + }else{ + return parameter+"Op"; + } + } + // for loading + public openLoading(){ + this.loading.open(); + } + public closeLoading(){ + this.loading.close(); + } +} diff --git a/searchPages/searchUtils/advancedSearchPage.module.ts b/searchPages/searchUtils/advancedSearchPage.module.ts new file mode 100644 index 00000000..df34b56c --- /dev/null +++ b/searchPages/searchUtils/advancedSearchPage.module.ts @@ -0,0 +1,33 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import{AdvancedSearchPageComponent} from './advancedSearchPage.component'; +import{SearchResultsModule} from './searchResults.module'; +import{LoadingModalModule} from '../../utils/modal/loadingModal.module'; +import {ReportsServiceModule} from '../../services/reportsService.module'; +import {SearchDownloadModule} from './searchDownload.module'; +import{SearchPagingModule} from './searchPaging.module'; + +import {AdvancedSearchFormModule} from '../searchUtils/advancedSearchForm.module'; +import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {HelperModule} from '../../utils/helper/helper.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule, SearchResultsModule, LoadingModalModule, ReportsServiceModule, SearchPagingModule, AdvancedSearchFormModule, SearchDownloadModule, PiwikServiceModule, HelperModule + ], + declarations: [ + AdvancedSearchPageComponent, +], + + providers:[ + PreviousRouteRecorder + ], + exports: [ + AdvancedSearchPageComponent, + ] +}) +export class AdvancedSearchPageModule { } diff --git a/searchPages/searchUtils/browseEntities.component.ts b/searchPages/searchUtils/browseEntities.component.ts new file mode 100644 index 00000000..868fe06a --- /dev/null +++ b/searchPages/searchUtils/browseEntities.component.ts @@ -0,0 +1,96 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {RefineFieldResultsService} from '../../services/refineFieldResults.service'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass} from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'browse-entities', + template: ` +
    + + + +
    +
    + +
    +
    +
    +` + +}) +export class BrowseEntitiesComponent { + public searchFields:SearchFields = new SearchFields(); + public filters =[]; + @Input() public baseUrl:string = ""; + @Input() public entityName:string = ""; + @Input() public refineFields: string[] ;//= this.searchFields.RESULT_REFINE_FIELDS; + public sub: any; + public errorCodes:ErrorCodes = new ErrorCodes(); + public status = this.errorCodes.LOADING; + public fieldIdsMap=this.searchFields.RESULT_REFINE_FIELDS; + + constructor ( private _refineFieldsService: RefineFieldResultsService ) { + // this.baseUrl = OpenaireProperties.getLinkToSearchPublications(); + + } + + public ngOnInit() { + for(var i=0; i < this.searchFields.HIDDEN_FIELDS.length; i++){ + var index = this.refineFields.indexOf(this.searchFields.HIDDEN_FIELDS[i]) ; + if(index > -1){ + this.refineFields.splice(index,1); + + } + } + this.getStats(); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + } + + +private getStats(){ + + this.status = this.errorCodes.LOADING; + this.sub = this._refineFieldsService.getRefineFieldsResultsByEntityName(this.refineFields,this.entityName).subscribe( + data => { + console.info("Get Stats for "+this.entityName+ ": [Total:"+data[0]+" ] [fields: "+data[1].length+"]"); + this.filters = data[1]; + this.status = this.errorCodes.DONE; + if(data[0] == 0 ){ + this.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //this.status = this.errorCodes.ERROR; + if(err.status == '404') { + this.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.status = this.errorCodes.ERROR; + } else { + this.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); +} +} diff --git a/searchPages/searchUtils/browseEntities.module.ts b/searchPages/searchUtils/browseEntities.module.ts new file mode 100644 index 00000000..2d8d3cda --- /dev/null +++ b/searchPages/searchUtils/browseEntities.module.ts @@ -0,0 +1,31 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {RefineFieldResultsServiceModule} from '../../services/refineFieldResultsService.module'; + +import {BrowseEntitiesComponent} from './browseEntities.component'; +import {BrowseStatisticComponent} from './browseStatistic.component'; + +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, ErrorMessagesModule, + RefineFieldResultsServiceModule, RouterModule + ], + declarations: [ + BrowseEntitiesComponent, + BrowseStatisticComponent + +], + + providers:[ + ], + exports: [ + BrowseEntitiesComponent, + BrowseStatisticComponent + ] +}) +export class BrowseEntitiesModule { } diff --git a/searchPages/searchUtils/browseStatistic.component.html b/searchPages/searchUtils/browseStatistic.component.html new file mode 100644 index 00000000..3eb79bc6 --- /dev/null +++ b/searchPages/searchUtils/browseStatistic.component.html @@ -0,0 +1,50 @@ + + {{filter.title}} + + + + + + + diff --git a/searchPages/searchUtils/browseStatistic.component.ts b/searchPages/searchUtils/browseStatistic.component.ts new file mode 100644 index 00000000..b0b78951 --- /dev/null +++ b/searchPages/searchUtils/browseStatistic.component.ts @@ -0,0 +1,42 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {RefineFieldResultsService} from '../../services/refineFieldResults.service'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass} from '../searchUtils/searchUtils.class'; +import {RouterHelper} from '../../utils/routerHelper.class'; +@Component({ + selector: 'browse-statistic', + templateUrl: 'browseStatistic.component.html' + +}) +export class BrowseStatisticComponent { + + @Input() public baseUrl:string = ""; + @Input() public filter:any = ""; + private _maxCharacters = 30; + public viewAll = false; + public routerHelper:RouterHelper = new RouterHelper(); + constructor () { + + } + + public ngOnInit() { + + + } + + quote(str:string){ + return '"'+str+'"'; + } + + private _formatName(value){ + return value.name+" ";//(((value.name+" ("+value.number+")").length >this._maxCharacters)?(value.name.substring(0,(this._maxCharacters - (" ("+value.number+")").length - ('...').length))+"..."):value.name) + } + +} diff --git a/searchPages/searchUtils/dateFilter.component.ts b/searchPages/searchUtils/dateFilter.component.ts new file mode 100644 index 00000000..f03eb76a --- /dev/null +++ b/searchPages/searchUtils/dateFilter.component.ts @@ -0,0 +1,73 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; + +import { Filter, Value, DateValue} from './searchHelperClasses.class'; +import {IMyOptions, IMyDateModel} from '../../utils/my-date-picker/interfaces/index'; +// import {IMyDateModel} from '../../../utils/my-date-picker/interfaces/my-date-model.interface'; +import {Dates} from '../../utils/string-utils.class'; + +@Component({ + selector: 'date-filter', + template: ` + + +
    + + + + +
    + + From + + To
    +
    + ` + +}) + +export class DateFilterComponent { + + @Input() dateValue = new DateValue("any"); + @Input() filterId; + + private myDatePickerOptions: IMyOptions = { + // other options... + dateFormat: 'yyyy-mm-dd', + selectionTxtFontSize: '15px', + height:'28px', + width: '100%', + editableDateField: false, + showClearDateBtn: false + }; + + // Initialized to specific date (09.10.2018). + public from;//: Object = { date: { year: 2018, month: 10, day: 9 } }; + public to;//: Object = { date: { year: 2018, month: 10, day: 9 } }; + +constructor() { + this.updateDefaultRangeDates(this.dateValue.from,this.dateValue.to); +} +updateDefaultRangeDates(df:Date,dt:Date){ + this.from = { date: { year: df.getFullYear(), month: (df.getMonth()+1), day: df.getDate() } }; + this.to = { date: { year: dt.getFullYear(), month: (dt.getMonth()+1), day: dt.getDate() } }; + } +typeChanged(type:string){ + this.dateValue.setDatesByType(type); + this.updateDefaultRangeDates(this.dateValue.from, this.dateValue.to); +} + +onFromDateChanged(event: IMyDateModel) { + this.dateValue.from = Dates.getDateFromString(event.formatted); + +} +onToDateChanged(event: IMyDateModel) { + this.dateValue.to = Dates.getDateFromString(event.formatted); + +}} diff --git a/searchPages/searchUtils/dateFilter.module.ts b/searchPages/searchUtils/dateFilter.module.ts new file mode 100644 index 00000000..0c5dca82 --- /dev/null +++ b/searchPages/searchUtils/dateFilter.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { MyDatePickerModule } from '../../utils/my-date-picker/my-date-picker.module'; +import {DateFilterComponent} from './dateFilter.component'; +@NgModule({ + imports: [ + CommonModule, FormsModule, MyDatePickerModule + ], + declarations: [ + DateFilterComponent +], + + providers:[ + ], + exports: [ + DateFilterComponent + ] +}) +export class DateFilterModule { } diff --git a/searchPages/searchUtils/searchDownload.component.ts b/searchPages/searchUtils/searchDownload.component.ts new file mode 100644 index 00000000..55df68d0 --- /dev/null +++ b/searchPages/searchUtils/searchDownload.component.ts @@ -0,0 +1,112 @@ +import {Component, Input, Output, EventEmitter, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {AlertModal} from '../../utils/modal/alert'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import {ReportsService} from '../../services/reports.service'; +import {ModalLoading} from '../../utils/modal/loading.component'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'search-download', + template: ` + + + + (CSV) + + + + + + ` +}) + +export class SearchDownloadComponent { + @Input() totalResults:number = 0; + @Input() csvParams: string; + @Input() type: string; + @ViewChild(AlertModal) alertApplyAll; + private downloadURLAPI: string; + + sub: any; + downloadFilePiwikSub: any; + + @ViewChild (ModalLoading) loading : ModalLoading ; + // Alert box when something is wrong with CSV requests + @ViewChild('AlertModalCsvError') alertCsvError; + + constructor ( private _reportsService: ReportsService, private _piwikService:PiwikService) {} + + ngOnInit() { + this.downloadURLAPI = OpenaireProperties.getCsvAPIURL(); + } + + ngOnDestroy() { + if(this.sub) { + this.sub.unsubscribe(); + } + if(this.downloadFilePiwikSub) { + this.downloadFilePiwikSub.unsubscribe(); + } + } + + denialOfDownload() { + this.alertApplyAll.isOpen = true; + this.alertApplyAll.cancelButton = true; + this.alertApplyAll.okButton = false; + this.alertApplyAll.alertTitle = "Download Results in CSV"; + this.alertApplyAll.message = "Sorry, but the results are too many! Use the api instead!"; + this.alertApplyAll.cancelButtonText = "Ok"; + + console.info("denial of Download"); + + } + downloadfile(url:string,filename:string){ + console.log("Downloading file: "+ url); + this.openLoading(); + this.setMessageLoading("Downloading CSV file"); + + this._reportsService.downloadCSVFile(url).subscribe( + data => { + this.closeLoading(); + window.open(window.URL.createObjectURL(data),filename+".csv"); + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.downloadFilePiwikSub = this._piwikService.trackDownload(url).subscribe(); + } + }, + error => { + console.log("Error downloading the file."); + this.closeLoading(); + this.confirmOpenCsvError(); + }, + () => console.log('Completed file download.') + ); + } + + + public openLoading(){ + if(this.loading){ + this.loading.open(); + } + } + public closeLoading(){ + if(this.loading){ + this.loading.close(); + } + } + public setMessageLoading(message: string){ + if(this.loading){ + this.loading.message = message; + } + } + + public confirmOpenCsvError(){ + this.alertCsvError.cancelButton = false; + this.alertCsvError.okButton = true; + this.alertCsvError.alertTitle = "ERROR DOWNLOADING CSV FILE"; + this.alertCsvError.message = "There was an error in csv downloading. Please try again later."; + this.alertCsvError.okButtonText = "OK"; + this.alertCsvError.open(); + } + +} diff --git a/searchPages/searchUtils/searchDownload.module.ts b/searchPages/searchUtils/searchDownload.module.ts new file mode 100644 index 00000000..1275de01 --- /dev/null +++ b/searchPages/searchUtils/searchDownload.module.ts @@ -0,0 +1,24 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchDownloadComponent} from './searchDownload.component'; +import {LoadingModalModule} from '../../utils/modal/loadingModal.module'; +import {AlertModalModule} from '../../utils/modal/alertModal.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, LoadingModalModule, AlertModalModule + ], + declarations: [ + SearchDownloadComponent +], + + providers:[ + ], + exports: [ + SearchDownloadComponent + + ] +}) +export class SearchDownloadModule { } diff --git a/searchPages/searchUtils/searchFilter.component.html b/searchPages/searchUtils/searchFilter.component.html new file mode 100644 index 00000000..fdf83db7 --- /dev/null +++ b/searchPages/searchUtils/searchFilter.component.html @@ -0,0 +1,67 @@ + +
      +
    • +
      {{_formatTitle(filter.title,filter.values.length)}} +
      + +
    • +
    diff --git a/searchPages/searchUtils/searchFilter.component.ts b/searchPages/searchUtils/searchFilter.component.ts new file mode 100644 index 00000000..a120673c --- /dev/null +++ b/searchPages/searchUtils/searchFilter.component.ts @@ -0,0 +1,144 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; + +import { Filter, Value} from './searchHelperClasses.class'; +import {Open} from '../../utils/modal/open.component'; + +@Component({ + selector: 'search-filter', + templateUrl: 'searchFilter.component.html' +}) + +export class SearchFilterComponent { + + @Input() filter:Filter; + @Input() showResultCount:boolean = true; + @Input() isDisabled:boolean = false; + @Input() addShowMore:boolean = true; + + public showAll:boolean = false; + public _maxCharacters:number =28; + + @Output() toggleModal = new EventEmitter(); + + @Output() modalChange = new EventEmitter(); + + + public isOpen:boolean=false; + + filterModalChange() { + console.info("Modal Changed"); + this.modalChange.emit({ + value: true + }); + //this.close(); + } + + constructor () { + } + + ngOnInit() { + + } + public _formatTitle(title,length){ + return (((title+" ("+length+")").length >this._maxCharacters)?(title.substring(0,(this._maxCharacters - (" ("+length+")").length - ('...').length))+"..."):title+" ("+((length >= 99)?length+"+":length)+")") + } + private _formatName(value){ + return value.name;//(((value.name+" ("+value.number+")").length >this._maxCharacters)?(value.name.substring(0,(this._maxCharacters - (" ("+value.number+")").length - ('...').length))+"..."):value.name) + } + toggleShowAll(){ + this.showAll = !this.showAll; + if(this.showAll == false) { + this.reorderFilterValues(); + } + } + + filterChange(selected:boolean){ + console.info("filter change: "+selected); + if(selected){ + this.filter.countSelectedValues++; + // this.reorderFilterValues(); + }else{ + this.filter.countSelectedValues--; + // this.reorderFilterValues(); + } + } + getSelectedValues(filter):any{ + var selected = []; + if(filter.countSelectedValues >0){ + for (var i=0; i < filter.values.length; i++){ + if(filter.values[i].selected){ + selected.push(filter.values[i]); + } + } + } + return selected; + + } + getNotSelectedValues(filter):any{ + var notSselected = []; + if(filter.countSelectedValues >0){ + for (var i=0; i < filter.values.length; i++){ + if(!filter.values[i].selected){ + notSselected.push(filter.values[i]); + } + } + }else { + notSselected = filter.values; + } + return notSselected; + } + reorderFilterValues() { + for(let value of this.filter.values) { + if(value.selected) { + let index: number = this.filter.values.indexOf(value); + let selectedValue:Value = this.filter.values[index]; + + this.filter.values.splice(index, 1); + this.filter.values.splice(0, 0, selectedValue); + } + } + } +// sliceSelected() { +// let values: Value[] = []; +// +// for(let value of this.filter.values) { +// if(value.selected) { +// let index: number = this.filter.values.indexOf(value); +// let selectedValue:Value = this.filter.values[index]; +// +// this.filter.values.splice(index, 1); +// this.filter.values.splice(0, 0, selectedValue); +// } +// } + + + toggle() { + this.toggleModal.emit({ + value: this.filter + }); + } + + + open() { + this.isOpen = true; + } + + close() { + this.isOpen = false; + } + + filterChange2(selected:boolean){ + + console.info("filter change2"); + if(selected){ + this.filter.countSelectedValues++; + // this.reorderFilterValues(); + }else{ + this.filter.countSelectedValues--; + // this.reorderFilterValues(); + } + this.close(); + } + +} diff --git a/searchPages/searchUtils/searchFilter.module.ts b/searchPages/searchUtils/searchFilter.module.ts new file mode 100644 index 00000000..3cc6792b --- /dev/null +++ b/searchPages/searchUtils/searchFilter.module.ts @@ -0,0 +1,24 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchFilterComponent} from './searchFilter.component'; +import{SearchFilterModalComponent} from './searchFilterModal.component'; +import {ModalModule} from '../../utils/modal/modal.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, ModalModule + ], + declarations: [ + SearchFilterComponent, SearchFilterModalComponent +], + + providers:[ + ], + exports: [ + SearchFilterComponent, SearchFilterModalComponent + + ] +}) +export class SearchFilterModule { } diff --git a/searchPages/searchUtils/searchFilterModal.component.ts b/searchPages/searchUtils/searchFilterModal.component.ts new file mode 100644 index 00000000..bb0ed624 --- /dev/null +++ b/searchPages/searchUtils/searchFilterModal.component.ts @@ -0,0 +1,104 @@ +import {Component, ViewEncapsulation, ComponentRef, ElementRef, Input, EventEmitter, Output} from '@angular/core'; +// import { DynamicComponentLoader} from '@angular/core'; + +import {Open} from '../../utils/modal/open.component'; +import { Filter} from './searchHelperClasses.class'; + +@Component({ + selector: 'modal-search-filter', + template: ` + + + `, + encapsulation: ViewEncapsulation.None, +}) +/** + * API to an open search filter window. + */ +export class SearchFilterModalComponent{ + @Input() filter: Filter; + @Input() showResultCount:boolean = true; + @Output() modalChange = new EventEmitter(); + + public isOpen:boolean=false; + + constructor( public _elementRef: ElementRef){} + + filterModalChange(selected:boolean) { + console.info("Modal Changed"); + this.filterChange(selected); + this.modalChange.emit({ + value: selected + }); + this.close(); + } + filterChange(selected:boolean){ + if(selected){ + this.filter.countSelectedValues++; + // this.reorderFilterValues(); + }else{ + this.filter.countSelectedValues--; + // this.reorderFilterValues(); + } + } + getSelectedValues(filter):any{ + var selected = []; + if(filter.countSelectedValues >0){ + for (var i=0; i < filter.values.length; i++){ + if(filter.values[i].selected){ + selected.push(filter.values[i]); + } + } + } + return selected; + + } + getNotSelectedValues(filter):any{ + var notSselected = []; + if(filter.countSelectedValues >0){ + for (var i=0; i < filter.values.length; i++){ + if(!filter.values[i].selected){ + notSselected.push(filter.values[i]); + } + } + }else { + notSselected = filter.values; + } + return notSselected; + } + + open() { + this.isOpen = true; + } + + close() { + this.isOpen = false; + } + +} diff --git a/searchPages/searchUtils/searchForm.component.ts b/searchPages/searchUtils/searchForm.component.ts new file mode 100644 index 00000000..0a6ba9a8 --- /dev/null +++ b/searchPages/searchUtils/searchForm.component.ts @@ -0,0 +1,52 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {RouterHelper} from '../../utils/routerHelper.class'; +import {Router} from '@angular/router'; + +@Component({ + selector: 'search-form', + template: ` + +
    + + + +
    + ` +}) + +export class SearchFormComponent { + @Input() isDisabled: boolean = false; + @Input() keyword: string = ''; + @Input() generalSearch: boolean = false; + @Input() placeholderText: string = "Type keywords"; + @Input() link: boolean = false; + public routerHelper:RouterHelper = new RouterHelper(); + + @Output() keywordChange = new EventEmitter(); + + constructor (private _router:Router) { + } + + ngOnInit() { + + } + + keywordChanged() { + console.info("inside form: "+this.keyword); + this.keywordChange.emit({ + value: this.keyword + }); + } + goTo() { + this._router.navigate(['/search/find'], { queryParams: this.routerHelper.createQueryParam('keyword',this.keyword) }); + } +} diff --git a/searchPages/searchUtils/searchForm.module.ts b/searchPages/searchUtils/searchForm.module.ts new file mode 100644 index 00000000..21a9d9b1 --- /dev/null +++ b/searchPages/searchUtils/searchForm.module.ts @@ -0,0 +1,23 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import{SearchFormComponent} from './searchForm.component'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule + ], + declarations: [ + SearchFormComponent +], + + providers:[ + ], + exports: [ + SearchFormComponent + + ] +}) +export class SearchFormModule { } diff --git a/searchPages/searchUtils/searchHelperClasses.class.ts b/searchPages/searchUtils/searchHelperClasses.class.ts new file mode 100644 index 00000000..c09b3440 --- /dev/null +++ b/searchPages/searchUtils/searchHelperClasses.class.ts @@ -0,0 +1,89 @@ +import {Dates} from '../../utils/string-utils.class'; +export class Filter{ + public title: string; // eg Type + public filterId: string; // type (name in url parameter) + public originalFilterId: string; // (in index) + public countSelectedValues: number = 0; + public values: Value[] = []; + public filterOperator: string ='or'; + + +} + +export class Value{ + public name: string; //eg Article, Journal + public id: string; //0001 + public selected: boolean = false; + public number: number = 0; + +} +export class AdvancedField{ + public id: string; // + public param:string; + public name: string; // + public type: string = "keyword"; //keyword, static or dynamic + public value: string = ''; + public operatorId: string; + public operatorName: string =""; + public valid: boolean = true; + public dateValue:DateValue = new DateValue("any"); + + constructor(id:string,param:string,name:string, type:string, value:string,operator:string){ + this.id = id; + this.param = param; + this.name = name; + this.type = type; + this.value = value; + this.operatorId = operator; + // this.operatorName = "AND"; + + } +} +export class DateValue{ + public types = ["any","range","1mon","2mon","3mon","6mon","12mon","2year","5year","10year"]; + public typesTitle = ["any","in the specified date range","in the last month","in the last 2 months","in the last 3 months","in the last 6 months","in the last year","in the last 2 years","in the last 5 years","in the last 10 years"]; + public type: string ; + public from:Date = new Date(); + public to:Date = new Date(); + constructor(type:string = "any"){ + this.setDatesByType(type); + } + public setDatesByType(type:string){ + if(this.types.indexOf(type) == -1){ + type=this.types[0]; + } + this.type = type; + this.to = Dates.getDateToday(); + if(this.type == "range" || this.type == "any"){ // for type "any" just to initiate with values + this.from = Dates.getDateXMonthsAgo(1); + }else if(this.type == "1mon"){ + this.from = Dates.getDateXMonthsAgo(1); + }else if(this.type == "2mon"){ + this.from = Dates.getDateXMonthsAgo(2); + }else if(this.type == "3mon"){ + this.from = Dates.getDateXMonthsAgo(3); + }else if(this.type == "6mon"){ + this.from = Dates.getDateXMonthsAgo(6); + }else if(this.type == "12mon"){ + this.from = Dates.getDateXMonthsAgo(12); + }else if(this.type == "2year"){ + this.from = Dates.getDateXYearsAgo(2); + }else if(this.type == "5year"){ + this.from = Dates.getDateXYearsAgo(5); + }else if(this.type == "10year"){ + this.from = Dates.getDateXYearsAgo(10); + } + } + +} +export class OPERATOR{ + public static AND: string ="and"; + public static OR: string ="or"; + public static NOT: string ="not"; + +} + +export class AutoCompleteValue{ + public id: string; + public label: string; +} diff --git a/searchPages/searchUtils/searchPage.component.html b/searchPages/searchUtils/searchPage.component.html new file mode 100644 index 00000000..029d3709 --- /dev/null +++ b/searchPages/searchUtils/searchPage.component.html @@ -0,0 +1,126 @@ +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + + More search options + + + +
    + Keywords: + + + {{filter.title}}: + + , + + + + + + Clear All + +
    + +
    + +
    +
    +
    + +
    +
    + + + +
    +
    + +
    Filter By:
    + +
    +
    + +
    +
    + + +
    +
    + + +
    + + +
    + +
    + +
    + +
    + + + + + + + + +
    + +
    + + +
    + +
    + +
    + + + +
    + +
    + + + + + + + + + +
    + +
    + +
    + +
    +
    +
    +
    +
    +
    diff --git a/searchPages/searchUtils/searchPage.component.ts b/searchPages/searchUtils/searchPage.component.ts new file mode 100644 index 00000000..145fdb92 --- /dev/null +++ b/searchPages/searchUtils/searchPage.component.ts @@ -0,0 +1,551 @@ +import {Component, Input, ViewChild, Output, EventEmitter,ElementRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {Location} from '@angular/common'; +import { Router} from '@angular/router'; + +import { Filter, Value} from './searchHelperClasses.class'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchUtilsClass} from './searchUtils.class'; +import {DOI, StringUtils} from '../../utils/string-utils.class'; +import {ModalLoading} from '../../utils/modal/loading.component'; +import { Meta} from '../../../angular2-meta'; +import{SearchFilterComponent} from './searchFilter.component'; +import {SearchFilterModalComponent} from './searchFilterModal.component'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import { ErrorCodes} from '../../utils/properties/openaireProperties'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + + +@Component({ + selector: 'search-page', + templateUrl: 'searchPage.component.html' + +}) +export class SearchPageComponent { + @Input() pageTitle = ""; + @Input() formPlaceholderText = "Type Keywords..."; + @Input() results = []; + @Input() filters = []; + @Input() type:string = ""; + @Input() entityType: string = ""; + @Input() searchUtils:SearchUtilsClass = new SearchUtilsClass(); + @Output() queryChange = new EventEmitter(); + @Input() baseUrl:string = ''; + @Input() showResultCount:boolean = true; + @Input() showRefine:boolean = true; + @Input() refineFields = []; + @Input() csvParams: string; + @Input() csvPath: string; + @Input() advancedSearchLink: string = ""; + @Input() tableViewLink: string; + @Input() disableForms: boolean = false; + @Input() loadPaging: boolean = true; + @Input() oldTotalResults: number = 0; + @Input() tableView: boolean = false; + @Input() searchFormClass: string = "searchForm"; + @ViewChild (ModalLoading) loading : ModalLoading ; + public fieldIdsMap;//: { [key:string]:{ name:string, operator:string, type:string, indexField:string, equalityOperator:string }}; + private searchFieldsHelper:SearchFields = new SearchFields(); + private queryParameters: Map = new Map(); + private baseURLWithParameters:string = ''; + private sub: any; piwiksub: any; + public countFilters= 0; + public parameterNames:string[] =[]; + public parameterValues:string[] =[]; + public showUnknownFilters:boolean = false; // when a filter exists in query but has no results, so no filters returned from the query + //@ViewChild (SearchFilterModalComponent) searchFilterModal : SearchFilterModalComponent ; + public currentFilter: Filter; + + constructor (private location: Location , private _meta: Meta,private element: ElementRef,private _piwikService:PiwikService, private router: Router) { + } + + ngOnInit() { + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + // this.updateBaseUrlWithParameters(this.filters); + this.updateTitle(this.pageTitle); + this.updateDescription("Openaire, search, repositories, open access, type, content provider, funder, project, " + this.type + "," +this.pageTitle); + if(typeof window !== 'undefined') { + this.updateUrl(OpenaireProperties.getBaseLink()+location.pathname); + } + if(typeof document !== 'undefined' && OpenaireProperties.isPiwikTrackEnabled()){ + this.piwiksub = this._piwikService.trackView(this.pageTitle).subscribe(); + } + } + ngAfterViewChecked(){ + + } + ngOnDestroy() { + if(this.piwiksub){ + this.piwiksub.unsubscribe(); + } + } + toggleModal($event) { + this.currentFilter = $event.value; + //this.searchFilterModal.open(); + } + + updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + + public getQueryParametersFromUrl(params){ + // var parameters = ""; + var allFqs = ""; + + this.queryParameters = new Map(); + for(var i=0; i< this.refineFields.length ; i++){ + var filterId = this.refineFields[i]; + + if(params[filterId] != undefined) { + this.queryParameters.set(filterId, StringUtils.URIDecode(params[filterId])); + let values = (StringUtils.URIDecode(this.queryParameters.get(filterId))).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); + var countvalues = 0; + var fq = ""; + for(let value of values) { + countvalues++; + var paramId = this.fieldIdsMap[filterId].param; + // parameters+='&' + paramId+ '='+ value;//+"&" + this.fieldIdsMap[paramId].operator + "="+((countvalues == 1)?"and":"or"); + fq+=(fq.length > 0 ? " " + "or" + " ":"" ) + filterId +" exact " +StringUtils.URIEncode(value); + } + if(countvalues > 0){ + fq="&fq="+fq; + } + allFqs += fq; + } + } + var keyword = params['keyword']; + var doiQuery = ""; + var keywordQuery = ""; + if((keyword && keyword.length > 0)){ + if((this.type == 'publications' ||this.type == 'research data')){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + doiQuery += "&"+doisParams; + }else { + keywordQuery += "&q="+StringUtils.URIEncode(keyword); + } + }else{ + keywordQuery += "&q="+StringUtils.URIEncode(keyword); + + } + } + return (doiQuery.length > 0 ? doiQuery:keywordQuery) + allFqs; + } + public getIndexQueryParametersFromUrl(params){ + // var parameters = ""; + var allFqs = ""; + + for(var i=0; i< this.refineFields.length ; i++){ + var filterId = this.refineFields[i]; + var fq = ""; + if(params[filterId] != undefined) { + this.queryParameters.set(filterId,decodeURIComponent(params[filterId])); + let values = (decodeURIComponent(this.queryParameters.get(filterId))).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); + var countvalues = 0 + for(let value of values) { + countvalues++; + // parameters+= ((countvalues == 1)?" and (":" or ")+ filterId+ '='+ value; + fq+=(fq.length > 0 ? " " + "or" + " ":"" ) + filterId + " exact " + value;//StringUtils.quote(value); + } + // parameters+= " ) "; + if(countvalues > 0){ + fq="&fq="+fq; + } + allFqs += fq; + } + + } + var keyword = params['keyword']; + var doiQuery = ""; + var keywordQuery = ""; + if((keyword && keyword.length > 0)){ + if((this.type == 'publications' ||this.type == 'research data')){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + doiQuery += "&"+doisParams; + } + }else{ + keywordQuery += "and ("+StringUtils.quote(StringUtils.URIEncode(keyword)) +")"; + + } + } + return (doiQuery.length > 0 ? doiQuery:keywordQuery) + allFqs; + +} + /* + * Mark as check the new filters that are selected, when you get them from search + */ + public checkSelectedFilters(filters:Filter[]){ + this.filters = filters; + for(var i=0; i< filters.length ; i++){ + var filter:Filter = filters[i]; + filter.countSelectedValues = 0; + if(this.queryParameters.get(filter.filterId) != undefined) { + let values = (decodeURIComponent(this.queryParameters.get(filter.filterId))).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); + for(let filterValue of filter.values) { + if(values.indexOf(StringUtils.quote(filterValue.id)) > -1) { + filterValue.selected = true; + filter.countSelectedValues++; + }else{ + filterValue.selected = false; + + } + } + }else{ + for(let filterValue of filter.values) { + filterValue.selected = false; + } + } + } + this.filterFilterValues(this.filters); + return filters; + } + /* + * For Funder filters - if funder selected + */ + public filterFilterValues(filters:Filter[]){ + var funders = []; + var funder_prefix = []; + for(var i=0; i< filters.length ; i++){ + + var filter:Filter = filters[i]; + // console.log(filter.filterId); + if(filter.filterId.indexOf("funder")!=-1 && this.queryParameters.get(filter.filterId) != undefined) { + let funders = (decodeURIComponent(this.queryParameters.get(filter.filterId))).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); + for(let funder of funders) { + console.log(funder); + funder_prefix.push(StringUtils.unquote(funder).split("____")[0]); + } + // console.log(funder_prefix ); + }else if(filter.filterId.indexOf("funding")!=-1){ + // console.log(" funding: "+filter.filterId ); + var filteredValues = [] + for(let filterValue of filter.values) { + var value_prefix = filterValue.id.split("____")[0]; + // console.log("Value prefix: "+value_prefix ); + if(funder_prefix.indexOf(value_prefix)!=-1){ + // console.log("here" + value_prefix); + filteredValues.push(filterValue); + } + + } + console.log("From " +filter.values.length+ "to "+filteredValues.length); + if(filteredValues.length > 0){ + filter.values = filteredValues; + } + } + + } + + return filters; + } + /* + * Update the url with proper parameters. This is used as base url in Paging Component + */ + public updateBaseUrlWithParameters(filters:Filter[]){ + this.baseURLWithParameters = this.baseUrl + this.createUrlParameters(filters,false); + + } + + /* + *Get The filters and create url parameters + */ + private createUrlParameters(filters:Filter[], includePage:boolean){ + var allLimits="";//location.search.slice(1); + this.queryParameters = new Map(); + this.parameterNames.splice(0,this.parameterNames.length); + this.parameterValues.splice(0,this.parameterValues.length); + + for (let filter of filters){ + var filterLimits=""; + if(filter.countSelectedValues > 0){ + for (let value of filter.values){ + if(value.selected == true){ + filterLimits+=((filterLimits.length == 0)?'':',') +'"'+ StringUtils.URIEncode(value.id)+'"'; + } + } + this.queryParameters.set(filter.filterId,filterLimits); + if(filterLimits.length > 0){ + this.parameterNames.push(filter.filterId); + this.parameterValues.push(filterLimits); + } + allLimits+=(allLimits.length==0?"?":"&")+((filterLimits.length == 0 )?'':filter.filterId + '='+ filterLimits) ; + } + } + if(this.searchUtils.keyword.length > 0 ){ + allLimits+=(allLimits.length==0?"?":"&")+'keyword=' + this.searchUtils.keyword; + this.parameterNames.push("keyword"); + this.parameterValues.push(this.searchUtils.keyword); + } + if(this.searchUtils.page != 1 && includePage){ + allLimits+=((allLimits.length == 0)?'?':'&') + 'page=' + this.searchUtils.page; + } + + return allLimits; + } + /* + * + */ + private createSearchQueryParameters(filters:Filter[]){ + var allFqs = ""; + for (let filter of filters){ + if(filter.countSelectedValues > 0){ + var fq = ""; + var count_selected=0; + for (let value of filter.values){ + if(value.selected == true){ + count_selected++; + fq+=(fq.length > 0 ? " " + filter.filterOperator + " ":"" ) + filter.filterId + " exact " + StringUtils.quote(StringUtils.URIEncode(value.id)); + } + } + fq="&fq="+fq; + allFqs += fq; + } + } + var doiQuery = ""; + var keywordQuery = ""; + if((this.searchUtils.keyword && this.searchUtils.keyword.length > 0)){ + if((this.type == 'publications' ||this.type == 'research data')){ + var DOIs:string[] = DOI.getDOIsFromString(this.searchUtils.keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + doiQuery += "&"+doisParams; + }else{ + keywordQuery += "&q="+StringUtils.URIEncode(this.searchUtils.keyword); + } + }else{ + keywordQuery += "&q="+StringUtils.URIEncode(this.searchUtils.keyword); + } + } + + return (doiQuery.length > 0 ? doiQuery:keywordQuery) + allFqs; + + } + private createIndexQueryParameters(filters:Filter[]){ + var allFqs = ""; + for (let filter of filters){ + if(filter.countSelectedValues > 0){ + var count_selected=0; + var fq = ""; + for (let value of filter.values){ + if(value.selected == true){ + count_selected++; + fq+=(fq.length > 0 ? " " + filter.filterOperator + " ":"" ) + filter.filterId + " exact " + StringUtils.quote(StringUtils.URIEncode(value.id)); + } + } + if(count_selected > 0){ + fq="&fq="+fq; + allFqs += fq; + } + } + } + var doiQuery = ""; + var keywordQuery = ""; + if((this.searchUtils.keyword && this.searchUtils.keyword.length > 0)){ + if((this.type == 'publications' ||this.type == 'research data')){ + var DOIs:string[] = DOI.getDOIsFromString(this.searchUtils.keyword); + var doisParams = ""; + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + doiQuery += "&"+doisParams; + } + }else{ + keywordQuery += " and ("+StringUtils.quote(StringUtils.URIEncode(this.searchUtils.keyword)) +")" + + } + } + return (doiQuery.length > 0 ? doiQuery:keywordQuery) + allFqs; + + } + public isFiltered(){ + var filtered=false; + this.showUnknownFilters = false; + for (let filter of this.filters){ + if(filter.countSelectedValues > 0){ + filtered = true; + break; + } + } + if(this.searchUtils.keyword.length > 0 ){ + filtered = true; + } + var errorCodes:ErrorCodes = new ErrorCodes(); + if(this.queryParameters.keys() && this.searchUtils.totalResults == 0 && this.searchUtils.status !=errorCodes.LOADING ){ + this.showUnknownFilters = true; + } + return filtered; + } + private clearKeywords(){ + if(this.searchUtils.keyword.length > 0 ){ + this.searchUtils.keyword =''; + } + this.goTo(1); + } + private clearFilters(){ + for (var i =0 ; i < this.filters.length; i++){ + for (var j=0; j < this.filters[i].countSelectedValues; j++){ + if(this.filters[i].values[j].selected){ + this.filters[i].values[j].selected = false; + } + this.filters[i].countSelectedValues = 0; + } + } + this.clearKeywords(); + + } + private removeFilter(value:Value,filter:Filter){ + filter.countSelectedValues--; + if(value.selected == true){ + value.selected = false; + } + this.goTo(1); + + } + goTo(page:number = 1){ + this.searchUtils.page = page; + console.info("searchUtils.page goto = "+this.searchUtils.page); + var urlParameters = this.createUrlParameters(this.filters,true); + console.info("urlParams : "+urlParameters); + this.updateBaseUrlWithParameters(this.filters); + var queryParameters = this.createSearchQueryParameters(this.filters); + console.info("queryParams : "+queryParameters); + var indexQuery = this.createIndexQueryParameters(this.filters); + + this.location.go(location.pathname,urlParameters); +/* Code For Piwik*/ + if (typeof localStorage !== 'undefined') { + localStorage.setItem('previousRoute', this.router.url); + } + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.pageTitle).subscribe(); + } + /* End Piwik Code */ + this.queryChange.emit({ + value: queryParameters, + index:indexQuery + + }); + if (typeof document !== 'undefined') { + this.element.nativeElement.scrollIntoView(); + } + } + filterChanged($event){ + console.info("filter Changed"); + this.goTo(1); + } + keywordChanged($event) { + this.searchUtils.keyword = $event.value; + this.goTo(1); + } + + /* + * Get A sub-array of this.refineFields array, which contains the ids of the selected filters + */ + public getSelectedFilters():string[] { + var selected:string[] = []; + for(var i=0; i < this.filters.length; i++){ + var filter:Filter = this.filters[i]; + if(filter.countSelectedValues > 0){ + selected.push(filter.filterId); + } + } + return selected; + } + /* + * Get A sub-array of this.refineFields array, which contains the ids of the selected parameters + */ + private getSelectedParameters():string[] { + var selected:string[] = []; + var params:string[] = Object.keys(this.queryParameters); + for(var i=0; i < params.length; i++){ + if(this.refineFields.indexOf(params[i]) > -1){ + selected.push(params[i]); + } + } + return selected; + } + /* + * Get A sub-array of this.refineFields array, which hides hidden fields (e.g Funding level 0,1,2,..), and contains those that depend on another fields (e.g Funding level 0 if Funder is selected ) + */ + public getFields():string[] { + var selected_filters:string[] = this.getSelectedFilters(); + if(selected_filters.length == 0){ + selected_filters = this.getSelectedParameters(); + } + var fields:string[] = []; + for(var i =0 ; i < this.refineFields.length;i++){ + var dependentTo = this.searchFieldsHelper.DEPENDENT_FIELDS[this.refineFields[i]]; + + //if filter is not marked as hidden OR it is hidden but it is dependent to a field that it IS selected + if(this.searchFieldsHelper.HIDDEN_FIELDS.indexOf(this.refineFields[i]) == -1 || (selected_filters.indexOf(dependentTo) != -1) || (selected_filters.indexOf(this.refineFields[i]) != -1) ){ + fields.push(this.refineFields[i]); + } + } + return fields; + } + /* + * Get a query string of all fields, that want to get from search (e.g. &fields=funderid&fields=projectstartyear&...)) + */ + public getRefineFieldsQuery():string{ + + var fields:string[] = this.getFields(); + var fieldsStr = "" + for(var i =0 ; i < fields.length ;i++){ + fieldsStr+="&fields="+fields[i]; + } + return "&refine=true"+fieldsStr; + } + + // for loading + public openLoading(){ + if(this.loading){ + this.loading.open(); + } + } + public closeLoading(){ + if(this.loading){ + this.loading.close(); + } + } + getSelectedValues(filter):any{ + var selected = []; + if(filter.countSelectedValues >0){ + for (var i=0; i < filter.values.length; i++){ + if(filter.values[i].selected){ + selected.push(filter.values[i]); + } + } + } + return selected; + + } +} diff --git a/searchPages/searchUtils/searchPage.module.ts b/searchPages/searchUtils/searchPage.module.ts new file mode 100644 index 00000000..39fc78fd --- /dev/null +++ b/searchPages/searchUtils/searchPage.module.ts @@ -0,0 +1,40 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import{SearchPageComponent} from './searchPage.component'; +import{SearchFormModule} from './searchForm.module'; +import{SearchResultsModule} from './searchResults.module'; +//import{DatasourceTableViewModule} from './datasourceTableView.module'; +//import{SearchFilterComponent} from './searchFilter.component'; +//import{SearchFilterModalComponent} from './searchFilterModal.component'; +import {SearchFilterModule} from './searchFilter.module'; +import{LoadingModalModule} from '../../utils/modal/loadingModal.module'; +import {ReportsServiceModule} from '../../services/reportsService.module'; +import{SearchPagingModule} from './searchPaging.module'; +import {SearchDownloadModule} from './searchDownload.module'; +import {ModalModule} from '../../utils/modal/modal.module'; +import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; +import {HelperModule} from '../../utils/helper/helper.module'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule,RouterModule, SearchFormModule, SearchResultsModule, + LoadingModalModule, ReportsServiceModule, + SearchPagingModule, SearchDownloadModule, ModalModule, SearchFilterModule, PiwikServiceModule, HelperModule + ], + declarations: [ + SearchPageComponent +], + + providers:[ + PreviousRouteRecorder + ], + exports: [ + SearchPageComponent + ] +}) +export class SearchPageModule { } diff --git a/searchPages/searchUtils/searchPageTableView.component.html b/searchPages/searchUtils/searchPageTableView.component.html new file mode 100644 index 00000000..ccd8c450 --- /dev/null +++ b/searchPages/searchUtils/searchPageTableView.component.html @@ -0,0 +1,197 @@ +
    +
    +
    +
    +
    +
    + +
    +
    +
    + Keywords: {{searchUtils.keyword}} + + + {{filter.title}}: + {{value.name}} + , + + + + + + Clear All + +
    +
    +
    +
    +
    + +
    + +
    + + +
    +
    + +
    Filter By:
    + +
    +
    + +
    +
    + +
    +
    + + +
    + +
    +
    +
    + + {{searchUtils.totalResults}} content providers, page {{searchUtils.page}} of {{(totalPages())}} + + + + +
    +
    + +
    +

    + + + + + +

    +
    + +
    + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + +
    Name + + + + + Type + + + + + Country + + + + + Institution + + + + + Compatibility + + + + +
    + + + + + [no title available] + + + + {{dataprovider.type}} + - + + {{country}}{{(i < ( dataprovider['countries'].slice(0,5).length-1))?", ":""}}{{(i == dataprovider['countries'].slice(0,5).length-1 && dataprovider['countries'].length > 5)?"...":""}} + - + + + {{org.name}}{{org.name}}{{(i < ( dataprovider['organizations'].slice(0,5).length-1))?", ":""}}{{(i == dataprovider['organizations'].slice(0,5).length-1 && dataprovider['organizations'].length > 5)?"...":""}} + + - + + {{dataprovider.compatibility}} + - +
    +
    + +
    +
    + + {{searchUtils.totalResults}} content providers, page {{searchUtils.page}} of {{(totalPages())}} + + + + +
    +
    + + + +
    + +
    +

    + + + + + +

    + + +
    +
    + + +
    + +
    +
    +
    diff --git a/searchPages/searchUtils/searchPageTableView.component.ts b/searchPages/searchUtils/searchPageTableView.component.ts new file mode 100644 index 00000000..50d206fa --- /dev/null +++ b/searchPages/searchUtils/searchPageTableView.component.ts @@ -0,0 +1,272 @@ +import {Component, Input, ViewChild, Output, EventEmitter, ChangeDetectorRef} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {Location} from '@angular/common'; +import { Filter, Value} from './searchHelperClasses.class'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchUtilsClass} from './searchUtils.class'; +import {DOI, StringUtils} from '../../utils/string-utils.class'; +import {ModalLoading} from '../../utils/modal/loading.component'; +import { Meta} from '../../../angular2-meta'; +import{SearchFilterComponent} from './searchFilter.component'; +import {SearchFilterModalComponent} from './searchFilterModal.component'; +import { ErrorCodes} from '../../utils/properties/openaireProperties'; +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; +import {ContentProvidersDatatablePipe} from '../../utils/pipes/contentProvidersDatatable.pipe'; +import {PiwikService} from '../../utils/piwik/piwik.service'; + +@Component({ + selector: 'search-page-table', + templateUrl:'searchPageTableView.component.html' + }) +export class SearchPageTableViewComponent { + @Input() pageTitle = ""; + @Input() results; + @Input() filters = []; + @Input() type:string = ""; + @Input() entityType: string = ""; + @Input() searchUtils:SearchUtilsClass;// = new SearchUtilsClass(); + //@Output() downloadClick = new EventEmitter(); + @Input() showResultCount:boolean = true; + @Input() showRefine:boolean = true; + @Input() refineFields = []; + //@Input() csvParams: string; + //@Input() csvPath: string; + @Input() searchViewLink: string; + @Input() disableForms: boolean = false; + @Input() searchFormClass: string = "searchForm"; +@Input() formPlaceholderText = "Type Keywords..."; + @ViewChild (ModalLoading) loading : ModalLoading ; + private searchFieldsHelper:SearchFields = new SearchFields(); + private queryParameters: Map = new Map(); + private sub: any; + public countFilters= 0; + public parameterNames:string[] =[]; + public parameterValues:string[] =[]; + + public triggerPipe: boolean = false; + + public rowsOnPage:number = 10; + @ViewChild('mf') table: any;//DataTable; + + @ViewChild (SearchFilterModalComponent) searchFilterModal : SearchFilterModalComponent ; + public currentFilter: Filter; + public errorCodes:ErrorCodes = new ErrorCodes(); + piwiksub: any; + + constructor (private location: Location , private _meta: Meta, private _piwikService:PiwikService, public cd: ChangeDetectorRef) { } + + ngOnInit() { + this.updateTitle(this.pageTitle); + this.updateDescription("Openaire, search, repositories, open access, type, content provider, funder, project, " + this.type + "," +this.pageTitle); + if(typeof window !== 'undefined') { + this.updateUrl(OpenaireProperties.getBaseLink()+location.pathname); + } + if(OpenaireProperties.isPiwikTrackEnabled() && (typeof document !== 'undefined')){ + this.piwiksub = this._piwikService.trackView(this.pageTitle).subscribe(); + } + } + ngOnDestroy() { + if(this.piwiksub){ + this.piwiksub.unsubscribe(); +} + } + public sortByOrganization = (dataprovider: any) => { + if(dataprovider.organizations && dataprovider.organizations.length > 0) { + return dataprovider.organizations[0].name.toUpperCase(); + } + return "-"; + } + + totalPages(): number { + let totalPages:any = this.searchUtils.totalResults/(this.rowsOnPage); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + return totalPages; + } + + refreshTable(page:number) { + this.searchUtils.page=page; + //this.table.mfActivePage=$event.value; + this.table.setPage(this.searchUtils.page, this.rowsOnPage); + } + + toggleModal($event) { + this.currentFilter = $event.value; + this.searchFilterModal.open(); + } + + updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } + +public getParametersFromUrl(params) { + for(var i=0; i< this.refineFields.length ; i++) { + var filterId = this.refineFields[i]; + if(params[filterId] != undefined) { + if(this.queryParameters == undefined){ + this.queryParameters = new Map(); + } + this.queryParameters[filterId]=decodeURIComponent(params[filterId]); + } + } +} + /* + * Mark as check the new filters that are selected, when you get them from search + */ + public checkSelectedFilters(filters:Filter[]){ + + this.filters = filters; + for(var i=0; i< filters.length ; i++){ + var filter:Filter = filters[i]; + filter.countSelectedValues = 0; + + if(this.queryParameters[filter.filterId] != undefined) { + let values = (decodeURIComponent(this.queryParameters[filter.filterId])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1); + for(let filterValue of filter.values) { + if(values.indexOf(StringUtils.quote(filterValue.id)) > -1) { + filterValue.selected = true; + filter.countSelectedValues++; + }else{ + filterValue.selected = false; + } + } + }else{ + for(let filterValue of filter.values) { + filterValue.selected = false; + } + } + } + + return filters; + } + + /* + * + */ + private createUrlParameters(filters:Filter[], includePage:boolean){ + var allLimits="";//location.search.slice(1); + this.parameterNames.splice(0,this.parameterNames.length); + this.parameterValues.splice(0,this.parameterValues.length); + + for (let filter of filters){ + var filterLimits=""; + if(filter.countSelectedValues > 0){ + for (let value of filter.values){ + if(value.selected == true){ + filterLimits+=((filterLimits.length == 0)?'':',') +'"'+ StringUtils.URIEncode(value.id)+'"'; + } + } + this.queryParameters[filter.filterId]=filterLimits; + if(filterLimits.length > 0){ + this.parameterNames.push(filter.filterId); + this.parameterValues.push(filterLimits); + } + allLimits+=(allLimits.length==0?"?":"&")+((filterLimits.length == 0 )?'':filter.filterId + '='+ filterLimits) ; + } + } + if(this.searchUtils.keyword.length > 0 ){ + allLimits+=(allLimits.length==0?"?":"&")+'keyword=' + this.searchUtils.keyword; + this.parameterNames.push("keyword"); + this.parameterValues.push(this.searchUtils.keyword); + } + + //if(this.searchUtils.page != 1 && includePage){ + // allLimits+=((allLimits.length == 0)?'?':'&') + 'page=' + this.searchUtils.page; + //} + + return allLimits; + } + + public isFiltered(){ + var filtered=false; + for (let filter of this.filters){ + if(filter.countSelectedValues > 0){ + filtered = true; + break; + } + } + if(this.searchUtils.keyword.length > 0 ){ + filtered = true; + } + return filtered; + } + private clearKeywords(){ + if(this.searchUtils.keyword.length > 0 ){ + this.searchUtils.keyword =''; + } + this.goTo(1, true); + } + private clearFilters(){ + for (var i =0 ; i < this.filters.length; i++) { + for (var j=0; j < this.filters[i].values.length; j++) { + if(this.filters[i].values[j].selected) { + this.filters[i].values[j].selected = false; + } + } + this.filters[i].countSelectedValues = 0; + } + this.clearKeywords(); + } + + private removeFilter(value:Value,filter:Filter){ + filter.countSelectedValues--; + if(value.selected == true){ + value.selected = false; + } + this.goTo(1, true); + } + goTo(page:number = 1, triggerPipe:boolean = true){ + this.refreshTable(page); + + var urlParameters = this.createUrlParameters(this.filters,true); + this.location.go(location.pathname,urlParameters); + if(triggerPipe) { + this.triggerPipe = !this.triggerPipe; + } + } + + filterChanged($event){ + this.goTo(1, true); + } + keywordChanged($event) { + this.searchUtils.keyword = $event.value; + this.goTo(1, true); + } +/* + downloadClicked($event) { + if($event.value == true) { + var queryParameters = this.createSearchQueryParameters(this.filters); + + this.downloadClick.emit({ + value: queryParameters + }); + } + } +*/ + + + getSelectedValues(filter):any{ + var selected = []; + if(filter.countSelectedValues >0){ + for (var i=0; i < filter.values.length; i++){ + if(filter.values[i].selected){ + selected.push(filter.values[i]); + } + } + } + return selected; + + } +} diff --git a/searchPages/searchUtils/searchPageTableView.module.ts b/searchPages/searchUtils/searchPageTableView.module.ts new file mode 100644 index 00000000..2586914e --- /dev/null +++ b/searchPages/searchUtils/searchPageTableView.module.ts @@ -0,0 +1,53 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import{SearchPageTableViewComponent} from './searchPageTableView.component'; +import{SearchFormModule} from './searchForm.module'; +import{SearchResultsModule} from './searchResults.module'; +//import{DatasourceTableViewModule} from './datasourceTableView.module'; +//import{SearchFilterComponent} from './searchFilter.component'; +//import{SearchFilterModalComponent} from './searchFilterModal.component'; +import {SearchFilterModule} from './searchFilter.module'; +import{LoadingModalModule} from '../../utils/modal/loadingModal.module'; +import {ReportsServiceModule} from '../../services/reportsService.module'; +import{SearchPagingModule} from './searchPaging.module'; +import {SearchDownloadModule} from './searchDownload.module'; +import {ModalModule} from '../../utils/modal/modal.module'; +import {PagingModule} from '../../utils/paging.module'; +import {DataTableModule} from "angular2-datatable"; +import {ContentProvidersDatatablePipe} from '../../utils/pipes/contentProvidersDatatable.pipe'; + +import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; +import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; + +import {HelperModule} from '../../utils/helper/helper.module'; +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule,RouterModule, SearchFormModule, SearchResultsModule, LoadingModalModule, + ReportsServiceModule, SearchPagingModule, SearchDownloadModule, ModalModule, PagingModule, + DataTableModule, SearchFilterModule, PiwikServiceModule, HelperModule, ErrorMessagesModule + ], + declarations: [ + SearchPageTableViewComponent//, + //SearchFilterComponent, + //SearchFilterModalComponent + , + ContentProvidersDatatablePipe +], + + providers:[ + PreviousRouteRecorder + ], + exports: [ + SearchPageTableViewComponent//, + //SearchFilterComponent, + //SearchFilterModalComponent + , + ContentProvidersDatatablePipe + ] +}) +export class SearchPageTableViewModule { } diff --git a/searchPages/searchUtils/searchPaging.component.ts b/searchPages/searchUtils/searchPaging.component.ts new file mode 100644 index 00000000..5044baa3 --- /dev/null +++ b/searchPages/searchUtils/searchPaging.component.ts @@ -0,0 +1,58 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ErrorCodes} from '../../utils/properties/openaireProperties'; + +@Component({ + selector: 'search-paging', + template: ` +
    +
    + {{searchUtils.totalResults}} {{type}}, page {{searchUtils.page}} of {{(totalPages(searchUtils.totalResults))}} +
    +
    + {{oldTotalResults}} {{type}}, page {{searchUtils.page}} of {{(totalPages(oldTotalResults))}} +
    +
    + +
    +
    + +
    +
    + ` +}) + +export class SearchPagingComponent { + @Input() searchUtils; + @Input() results; + @Input() baseUrl; + @Input() type; + @Input() parameterNames:string[]; + @Input() parameterValues:string[]; + + @Input() loadPaging: boolean = true; + @Input() oldTotalResults: number = 0; + + public totalResults: number = 0; + public errorCodes:ErrorCodes = new ErrorCodes(); + + // @Input() totalResults:number = 0; + constructor () {} + + ngOnInit() { + // this.totalResults = this.searchUtils.totalResults; + // if(!this.loadPaging && this.totalResults == 0) { + // this.totalResults = this.oldTotalResults; + // } + } + + totalPages(totalResults: number): number { + let totalPages:any = totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + return totalPages; + } + + +} diff --git a/searchPages/searchUtils/searchPaging.module.ts b/searchPages/searchUtils/searchPaging.module.ts new file mode 100644 index 00000000..4a403bd1 --- /dev/null +++ b/searchPages/searchUtils/searchPaging.module.ts @@ -0,0 +1,23 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchPagingComponent} from './searchPaging.component'; +import{PagingModule} from '../../utils/paging.module'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, PagingModule + ], + declarations: [ + SearchPagingComponent +], + + providers:[ + ], + exports: [ + SearchPagingComponent + + ] +}) +export class SearchPagingModule { } diff --git a/searchPages/searchUtils/searchResult.component.html b/searchPages/searchUtils/searchResult.component.html new file mode 100644 index 00000000..23393e07 --- /dev/null +++ b/searchPages/searchUtils/searchResult.component.html @@ -0,0 +1,139 @@ + diff --git a/searchPages/searchUtils/searchResult.component.ts b/searchPages/searchUtils/searchResult.component.ts new file mode 100644 index 00000000..d071ad5d --- /dev/null +++ b/searchPages/searchUtils/searchResult.component.ts @@ -0,0 +1,53 @@ +import {Component, Input} from '@angular/core'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../utils/routerHelper.class'; + +@Component({ + selector: 'search-result', + templateUrl:'searchResult.component.html' +}) + +export class SearchResultComponent { + @Input() results: SearchResult[]; + @Input() status: number; + @Input() type: string; + @Input() showLoading: boolean = false; + @Input() showSubjects: boolean = false; + @Input() showOrganizations: boolean = true; + @Input() custom_class: string = "search-results"; + + public urlParam: string; + public linkToAdvancedSearchPage: string; + public errorCodes:ErrorCodes = new ErrorCodes(); + public routerHelper:RouterHelper = new RouterHelper(); + public errorMessage: string = "No results found"; + + constructor () {} + + ngOnInit() { + if(this.type == "publication") { + this.linkToAdvancedSearchPage = OpenaireProperties.getLinkToAdvancedSearchPublications(); + this.urlParam = "articleId"; + } else if(this.type == "dataset") { + this.linkToAdvancedSearchPage = OpenaireProperties.getLinkToAdvancedSearchDatasets(); + this.urlParam = "datasetId"; + } else if(this.type == "software") { + this.linkToAdvancedSearchPage = OpenaireProperties.getLinkToAdvancedSearchSoftware(); + this.urlParam = "softwareId"; + } else if(this.type == "project") { + this.linkToAdvancedSearchPage = OpenaireProperties.getLinkToAdvancedSearchProjects(); + this.urlParam = "projectId"; + } else if(this.type == "organization") { + this.linkToAdvancedSearchPage = OpenaireProperties.getLinkToAdvancedSearchOrganizations(); + this.urlParam = "organizationId"; + } else if(this.type == "dataprovider") { + this.linkToAdvancedSearchPage = OpenaireProperties.getLinkToAdvancedSearchDataProviders(); + this.urlParam = "datasourceId"; + } + } + + public quote(params: string):string { + return '"'+params+'"'; + } +} diff --git a/searchPages/searchUtils/searchResults.module.ts b/searchPages/searchUtils/searchResults.module.ts new file mode 100644 index 00000000..0ca38971 --- /dev/null +++ b/searchPages/searchUtils/searchResults.module.ts @@ -0,0 +1,29 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; + +import {SearchResult} from '../../utils/entities/searchResult'; +import {SearchResultComponent} from './searchResult.component'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + RouterModule, ErrorMessagesModule + ], + declarations: [ + SearchResultComponent, + +], + + providers:[ + ], + exports: [ + + SearchResultComponent + + ] +}) +export class SearchResultsModule { } diff --git a/searchPages/searchUtils/searchUtils.class.ts b/searchPages/searchUtils/searchUtils.class.ts new file mode 100644 index 00000000..da9fb9cb --- /dev/null +++ b/searchPages/searchUtils/searchUtils.class.ts @@ -0,0 +1,10 @@ +export class SearchUtilsClass{ + page:number = 1; + size:number = 10; + status:number = 1; + keyword:string = ""; + baseUrl:string = ""; + totalResults = 0; + totalResultsNoFilters:number; // for organization landing - tab with projects + +} diff --git a/searchPages/searchUtils/tabResult.component.html b/searchPages/searchUtils/tabResult.component.html new file mode 100644 index 00000000..cf370265 --- /dev/null +++ b/searchPages/searchUtils/tabResult.component.html @@ -0,0 +1,122 @@ + diff --git a/searchPages/searchUtils/tabResult.component.ts b/searchPages/searchUtils/tabResult.component.ts new file mode 100644 index 00000000..39576e56 --- /dev/null +++ b/searchPages/searchUtils/tabResult.component.ts @@ -0,0 +1,31 @@ +import {Component, Input} from '@angular/core'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {ErrorCodes} from '../../utils/properties/openaireProperties'; +import {RouterHelper} from '../../utils/routerHelper.class'; + +@Component({ + selector: 'tab-result', + templateUrl: 'tabResult.component.html' + }) + +export class TabResultComponent { + @Input() results: SearchResult[]; + @Input() status: number; + @Input() type: string; + @Input() urlParam: string; + @Input() showLoading: boolean = false; + @Input() showOrganizations: boolean = true; + + public errorCodes:ErrorCodes = new ErrorCodes(); + public routerHelper:RouterHelper = new RouterHelper(); + public errorMessage: string = "No results found"; + constructor () { + + } + + ngOnInit() {} + + public quote(params: string):string { + return '"'+params+'"'; + } +} diff --git a/searchPages/searchUtils/tabResult.module.ts b/searchPages/searchUtils/tabResult.module.ts new file mode 100644 index 00000000..589b5623 --- /dev/null +++ b/searchPages/searchUtils/tabResult.module.ts @@ -0,0 +1,23 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchResult} from '../../utils/entities/searchResult'; +import {TabResultComponent} from './tabResult.component'; +import {RouterModule} from '@angular/router'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + RouterModule + ], + declarations: [ + TabResultComponent, + ], + providers:[ + ], + exports: [ + TabResultComponent + ] +}) +export class TabResultModule { } diff --git a/searchPages/simple/searchDataProviders.module.ts b/searchPages/simple/searchDataProviders.module.ts new file mode 100644 index 00000000..27db9dde --- /dev/null +++ b/searchPages/simple/searchDataProviders.module.ts @@ -0,0 +1,32 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchDataprovidersComponent} from './searchDataproviders.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {DataProvidersServiceModule} from '../../services/dataProvidersService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + DataProvidersServiceModule, + SearchFormModule, SearchResultsModule, SearchPageModule + + ], + declarations: [ + SearchDataprovidersComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchDataprovidersComponent + ] +}) +export class SearchDataProvidersModule { } diff --git a/searchPages/simple/searchDataproviders.component.ts b/searchPages/simple/searchDataproviders.component.ts new file mode 100644 index 00000000..23f5a838 --- /dev/null +++ b/searchPages/simple/searchDataproviders.component.ts @@ -0,0 +1,360 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-dataproviders', + template: ` + + + + + ` +}) +export class SearchDataprovidersComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public totalResults:number = 0 ; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public _location:Location; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.DATASOURCE_REFINE_FIELDS; + public fieldIdsMap= this.searchFields.DATASOURCE_FIELDS; + public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public csvParams: string; + + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + + constructor (private route: ActivatedRoute, private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.page =1; + this.baseUrl = OpenaireProperties.getLinkToSearchDataProviders(); + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + var firstLoad =true; + + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + var refine = true; + if(this.searchUtils.page != ((params['page']=== undefined)?1:+params['page']) && this.filters && !firstLoad){ + refine = false; + + } + firstLoad = false; + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + + var queryParameters = this.searchPage.getQueryParametersFromUrl(params); + this._getResults(queryParameters, refine, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + public getNumForEntity(entity: string, id:string) { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + if(id != "" && entity != "") { + + this._searchDataprovidersService.numOfEntityDataproviders(id, entity).subscribe( + data => { + this.searchUtils.totalResults = data; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + } + + public getNumForSearch(keyword: string) { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this._searchDataprovidersService.numOfDataproviders(keyword).subscribe( + data => { + this.searchUtils.totalResults = data; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + +public getResultsForDeposit(id:string, type:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.status = errorCodes.LOADING; + if(id != "") { + + this._searchDataprovidersService.searchDataprovidersForDeposit(id,type, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders forDeposit: [id:"+id+", type:"+type+" ] [total results:"+this.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + public getResultsForEntity(entity:string, id:string, page: number, size: number){ + var parameters = ""; + + if(entity == "organization") { + parameters = "organizations/"+id; + } + + if(parameters != "") { + + this._searchDataprovidersService.searchDataprovidersForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + } + + public getResultsForDataproviders(id:string, page: number, size: number){ + + this._searchDataprovidersService.getDataProvidersforEntityRegistry(id, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders for Entity Registry: [Id:"+id+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + public getResults(keyword:string,refine:boolean, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + parameters = "q="+ keyword; + } + this._getResults(parameters,refine,page,this.searchUtils.size); + } + private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters; + + // if(!refine && !this.searchPage){ + // this.searchPage = new SearchPageComponent(this._location); + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchDataprovidersService.searchDataproviders(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, this.searchPage.getFields()).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Content Providers: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refine){ + this.filters = data[2]; + } + this.searchPage.checkSelectedFilters(this.filters); + // this.filters = this.searchPage.checkSelectedFilters(data[2]); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + this._getResults(parameters, true, this.searchUtils.page, this.searchUtils.size); + } +} diff --git a/searchPages/simple/searchDatasets.component.ts b/searchPages/simple/searchDatasets.component.ts new file mode 100644 index 00000000..4fc0c57a --- /dev/null +++ b/searchPages/simple/searchDatasets.component.ts @@ -0,0 +1,275 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchDatasetsService} from '../../services/searchDatasets.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; +import {DOI} from '../../utils/string-utils.class'; + +@Component({ + selector: 'search-datasets', + template: ` + + + + ` +}) + +export class SearchDatasetsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters: Filter[] =[]; + // public totalResults:number = 0 ; + public baseUrl:string; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + private sub: any; + private subResults: any; + private searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.RESULT_REFINE_FIELDS; + public fieldIdsMap=this.searchFields.RESULT_FIELDS; + private urlParams : Map; + private _location:Location; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + constructor (private route: ActivatedRoute, private _searchDatasetsService: SearchDatasetsService ) { + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.page =1; + this.baseUrl = OpenaireProperties.getLinkToSearchDatasets(); + + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.type = "research data"; + var firstLoad =true; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + var refine = true; + if(this.searchUtils.page != ((params['page']=== undefined)?1:+params['page']) && this.filters && !firstLoad){ + refine = false; + } + firstLoad = false; + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + + var queryParameters = this.searchPage.getQueryParametersFromUrl(params); + this._getResults(queryParameters, refine, this.searchUtils.page, this.searchUtils.size); + + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + +public getResultsForEntity(entity:string, id:string, page: number, size: number){ + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id; + } + + if(parameters != "") { + + this._searchDatasetsService.searchDatasetsForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForDataproviders(id:string, resultsFrom:string, page: number, size: number){ + var parameters; + if(resultsFrom == "collectedFrom") { + parameters = "datasets?fq=collectedfromdatasourceid exact "+'"'+id+'"'; + } else if(resultsFrom == "hostedBy") { + parameters = "datasets?fq=resulthostingdatasourceid exact "+'"'+id+'"'; + } + + if(parameters != "") { + + this._searchDatasetsService.searchDatasetsForDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data for Dataproviders: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResults(keyword:string,refine:boolean, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + parameters += "&"+doisParams; + }else{ + parameters = "q=" + keyword; + } + } + this._getResults(parameters,refine,page,size); +} +private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters; + + // if(!refine && !this.searchPage){ + // this.searchPage = new SearchPageComponent(this._location); + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchDatasetsService.searchDatasets(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, this.searchPage.getFields()).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refine){ + this.filters = data[2]; + } + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); +} + + + + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + //this.getResults(parameters, this.searchUtils.page, this.searchUtils.size, "searchPage"); + this._getResults(parameters, true, this.searchUtils.page, this.searchUtils.size); + } +} diff --git a/searchPages/simple/searchDatasets.module.ts b/searchPages/simple/searchDatasets.module.ts new file mode 100644 index 00000000..1a1aa1c1 --- /dev/null +++ b/searchPages/simple/searchDatasets.module.ts @@ -0,0 +1,32 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchDatasetsComponent} from './searchDatasets.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {DatasetsServiceModule} from '../../services/datasetsService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + DatasetsServiceModule, + SearchFormModule, SearchResultsModule, SearchPageModule + + ], + declarations: [ + SearchDatasetsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchDatasetsComponent + ] +}) +export class SearchDatasetsModule { } diff --git a/searchPages/simple/searchOrganizations.component.ts b/searchPages/simple/searchOrganizations.component.ts new file mode 100644 index 00000000..2989d8e4 --- /dev/null +++ b/searchPages/simple/searchOrganizations.component.ts @@ -0,0 +1,175 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; +import {SearchOrganizationsService} from '../../services/searchOrganizations.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-organizations', + template: ` + + + + + ` + +}) +export class SearchOrganizationsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; + public subResults: any; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.ORGANIZATION_REFINE_FIELDS; + public fieldIdsMap = this.searchFields.ORGANIZATION_FIELDS; + public urlParams : Map; + public _location:Location; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + + constructor (private route: ActivatedRoute, private _searchOrganizationsService: SearchOrganizationsService ) { + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.page =1; + this.baseUrl = OpenaireProperties.getLinkToSearchOrganizations(); + + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + var firstLoad = true; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + var refine = true; + if(this.searchUtils.page != ((params['page']=== undefined)?1:+params['page']) && this.filters && !firstLoad){ + refine = false; + + } + firstLoad = false; + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + + var queryParameters = this.searchPage.getQueryParametersFromUrl(params); + this._getResults(queryParameters, refine, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + + public getResults(keyword:string,refine:boolean, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + parameters = "q=" + keyword; + } + this._getResults(parameters,refine,page,this.searchUtils.size); + } + private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters; + + // if(!refine && !this.searchPage){ + // this.searchPage = new SearchPageComponent(this._location); + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchOrganizationsService.searchOrganizations(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, this.searchPage.getFields()).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Organizations: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refine){ + this.filters = data[2]; + } + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + console.info("queryChanged: Execute search query "+parameters); + this._getResults(parameters, true, this.searchUtils.page, this.searchUtils.size); + } +} diff --git a/searchPages/simple/searchOrganizations.module.ts b/searchPages/simple/searchOrganizations.module.ts new file mode 100644 index 00000000..cd5bf990 --- /dev/null +++ b/searchPages/simple/searchOrganizations.module.ts @@ -0,0 +1,31 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchOrganizationsComponent} from './searchOrganizations.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {OrganizationsServiceModule} from '../../services/organizationsService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + OrganizationsServiceModule, + SearchFormModule, SearchResultsModule, SearchPageModule + + ], + declarations: [ + SearchOrganizationsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchOrganizationsComponent + ] +}) +export class SearchOrganizationsModule { } diff --git a/searchPages/simple/searchProjects.component.ts b/searchPages/simple/searchProjects.component.ts new file mode 100644 index 00000000..24659305 --- /dev/null +++ b/searchPages/simple/searchProjects.component.ts @@ -0,0 +1,213 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; +import {SearchProjectsService} from '../../services/searchProjects.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; + +@Component({ + selector: 'search-projects', + template: ` + + + + ` + +}) +export class SearchProjectsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters: Filter[] =[]; + public baseUrl:string; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; + public subResults: any; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.PROJECT_REFINE_FIELDS; + public fieldIdsMap = this.searchFields.PROJECT_FIELDS; + public urlParams : Map; + public _location:Location; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + + constructor (private route: ActivatedRoute, private _searchProjectsService: SearchProjectsService) { + console.info(" constructor SearchProjectsComponent "+this.refineFields.length); + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.page =1; + this.baseUrl = OpenaireProperties.getLinkToSearchProjects(); + + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + console.info(" ngOnInit SearchProjectsComponent "+this.refineFields.length); + //get refine field filters from url parameters + var firstLoad = true; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + //get keyword from url parameters + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + var refine = true; + if(this.searchUtils.page != ((params['page']=== undefined)?1:+params['page']) && this.filters && !firstLoad){ + refine = false; + + } + firstLoad = false; + //get page from url parameters + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + var queryParameters = this.searchPage.getQueryParametersFromUrl(params); + this._getResults(queryParameters, refine, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + public getResults(keyword:string,refine:boolean, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + parameters = "q="+keyword; + } + this._getResults(parameters,refine,page,this.searchUtils.size); + } + private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters; + + // if(!refine && !this.searchPage){ + // this.searchPage = new SearchPageComponent(this._location); + // } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchProjectsService.searchProjects(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, this.searchPage.getFields()).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Projects: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refine){ + this.filters = data[2]; + } + this.searchPage.checkSelectedFilters(this.filters); + // this.filters = this.searchPage.checkSelectedFilters(data[2]); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); + } + + public getResultsForDataproviders(id:string, page: number, size: number){ + + this._searchProjectsService.getProjectsforDataProvider(id, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Projects for Dataproviders: [Id:"+id+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + + public queryChanged($event) { + this.loadPaging = true; + + this.urlParams = undefined; + var parameters = $event.value; + this._getResults(parameters, true, this.searchUtils.page, this.searchUtils.size); + } + +} diff --git a/searchPages/simple/searchProjects.module.ts b/searchPages/simple/searchProjects.module.ts new file mode 100644 index 00000000..c8e1b094 --- /dev/null +++ b/searchPages/simple/searchProjects.module.ts @@ -0,0 +1,32 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchProjectsComponent} from './searchProjects.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {ProjectsServiceModule} from '../../services/projectsService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + ProjectsServiceModule, + SearchFormModule, SearchResultsModule, SearchPageModule + + ], + declarations: [ + SearchProjectsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchProjectsComponent + ] +}) +export class SearchProjectsModule { } diff --git a/searchPages/simple/searchPublications.component.ts b/searchPages/simple/searchPublications.component.ts new file mode 100644 index 00000000..ff643a03 --- /dev/null +++ b/searchPages/simple/searchPublications.component.ts @@ -0,0 +1,308 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; + +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass} from '../searchUtils/searchUtils.class'; +import {DOI} from '../../utils/string-utils.class'; + +@Component({ + selector: 'search-publications', + template: ` + + + + + ` + +}) +export class SearchPublicationsComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters =[]; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public baseUrl:string = ""; + public sub: any; + public subResults: any; + public searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.RESULT_REFINE_FIELDS; + public fieldIdsMap=this.searchFields.RESULT_FIELDS; + //: { [key:string] :{ name:string, operator:string, type:string, indexField:string, equalityOperator:string }} = this.searchFields.PUBLICATION_FIELDS_MAP; + public urlParams : Map; + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + public _location:Location; + + public CSV: any = { "columnNames": ["Title", "Authors", "Publication Year", "DOI", + /*"Download From", "Publication type", "Journal",*/ + "Funder", "Project Name (GA Number)", "Access"], + "export":[] + }; + public CSVDownloaded = false; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + constructor (private route: ActivatedRoute, private _searchPublicationsService: SearchPublicationsService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.page =1; + this.baseUrl = OpenaireProperties.getLinkToSearchPublications(); + + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.type = "publications"; + var firstLoad =true; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + var refine = true; + if(this.searchUtils.page != ((params['page']=== undefined)?1:+params['page']) && this.filters && !firstLoad){ + refine = false; + + } + firstLoad = false; + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + var queryParameters = this.searchPage.getQueryParametersFromUrl(params); + this._getResults(queryParameters, refine, this.searchUtils.page, this.searchUtils.size); + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + +public getResultsForEntity(entity:string, id:string, page: number, size: number){ + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id; + } + + if(parameters != "") { + + this._searchPublicationsService.searchPublicationsForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Publications for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForDataproviders(id:string, resultsFrom:string, page: number, size: number){ + var parameters; + if(resultsFrom == "collectedFrom") { + parameters = "publications?fq=collectedfromdatasourceid exact "+'"'+id+'"'; + } else if(resultsFrom == "hostedBy") { + parameters = "publications?fq=resulthostingdatasourceid exact "+'"'+id+'"'; + } + + if(parameters != "") { + + this._searchPublicationsService.searchPublicationsForDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Publications for Dataproviders: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResults(keyword:string,refine:boolean, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + parameters += "&"+doisParams; + }else{ + parameters = "q=" + keyword; + } + } + this._getResults(parameters,refine,page,size); +} + +private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters; + + // if(!refine && !this.searchPage){ + // this.searchPage = new SearchPageComponent(this._location); + // } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchPublicationsService.searchPublications(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, this.searchPage.getFields()).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Publications: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refine){ + this.filters = data[2]; + } + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + + //var errorCodes:ErrorCodes = new ErrorCodes(); + + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + + } + ); +} +/* +public getAggregatorResults(id:string, page: number, size: number){ + this.subResults = this._searchPublicationsService.searchAggregators('&fq=collectedfromdatasourceid exact "'+id+'"',"&refine=true&fields=resulthostingdatasource" , page, size).subscribe( + data => { + this.results = data; + + var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = errorCodes.ERROR; + } + ); +}*/ + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + console.info("queryChanged: Execute search query "+parameters); + console.info("Search Pubs::page "+this.searchUtils.page); + this._getResults(parameters, true, this.searchUtils.page, this.searchUtils.size); + } + + +} diff --git a/searchPages/simple/searchPublications.module.ts b/searchPages/simple/searchPublications.module.ts new file mode 100644 index 00000000..b76d203c --- /dev/null +++ b/searchPages/simple/searchPublications.module.ts @@ -0,0 +1,32 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchPublicationsComponent} from './searchPublications.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +//import {SearchFilterModalModule} from '../searchUtils/searchFilterModal.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; +import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + PublicationsServiceModule, + SearchFormModule, SearchResultsModule, SearchPageModule + + ], + declarations: [ + SearchPublicationsComponent + ], + providers:[FreeGuard, IsRouteEnabled], + exports: [ + SearchPublicationsComponent + ] +}) +export class SearchPublicationsModule { } diff --git a/searchPages/simple/searchSoftware.component.ts b/searchPages/simple/searchSoftware.component.ts new file mode 100644 index 00000000..5105cb93 --- /dev/null +++ b/searchPages/simple/searchSoftware.component.ts @@ -0,0 +1,275 @@ +import {Component, Input, ViewChild} from '@angular/core'; +import { ActivatedRoute} from '@angular/router'; +import {Location} from '@angular/common'; +import { Filter, Value} from '../searchUtils/searchHelperClasses.class'; + +import {SearchSoftwareService} from '../../services/searchSoftware.service'; +import {SearchResult} from '../../utils/entities/searchResult'; +import {OpenaireProperties, ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; +import {SearchPageComponent } from '../searchUtils/searchPage.component'; +import {SearchUtilsClass } from '../searchUtils/searchUtils.class'; +import {DOI} from '../../utils/string-utils.class'; + +@Component({ + selector: 'search-software', + template: ` + + + + ` +}) + +export class SearchSoftwareComponent { + private errorCodes: ErrorCodes; + + public results =[]; + public filters: Filter[] =[]; + // public totalResults:number = 0 ; + public baseUrl:string; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + private sub: any; + private subResults: any; + private searchFields:SearchFields = new SearchFields(); + public refineFields: string[] = this.searchFields.RESULT_REFINE_FIELDS; + public fieldIdsMap=this.searchFields.RESULT_FIELDS; + private urlParams : Map; + private _location:Location; + public csvParams: string; + public disableForms: boolean = false; + public loadPaging: boolean = true; + public oldTotalResults: number = 0; + + @ViewChild (SearchPageComponent) searchPage : SearchPageComponent ; + constructor (private route: ActivatedRoute, private _searchSoftwareService: SearchSoftwareService ) { + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this.searchUtils.page =1; + this.baseUrl = OpenaireProperties.getLinkToSearchSoftware(); + + } + + public ngOnInit() { + this.searchPage.refineFields = this.refineFields; + this.searchPage.fieldIdsMap = this.fieldIdsMap; + this.searchPage.type = "software"; + var firstLoad =true; + this.sub = this.route.queryParams.subscribe(params => { + if(params['page'] && this.searchUtils.page != params['page']) { + this.loadPaging = false; + this.oldTotalResults = this.searchUtils.totalResults; + } + + this.searchUtils.keyword = (params['keyword']?params['keyword']:''); + var refine = true; + if(this.searchUtils.page != ((params['page']=== undefined)?1:+params['page']) && this.filters && !firstLoad){ + refine = false; + } + firstLoad = false; + this.searchUtils.page = (params['page']=== undefined)?1:+params['page']; + + var queryParameters = this.searchPage.getQueryParametersFromUrl(params); + this._getResults(queryParameters, refine, this.searchUtils.page, this.searchUtils.size); + + }); + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + +public getResultsForEntity(entity:string, id:string, page: number, size: number){ + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id; + } + + if(parameters != "") { + + this._searchSoftwareService.searchSoftwareForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForDataproviders(id:string, resultsFrom:string, page: number, size: number){ + var parameters; + if(resultsFrom == "collectedFrom") { + parameters = "software?fq=collectedfromdatasourceid exact "+'"'+id+'"'; + } else if(resultsFrom == "hostedBy") { + parameters = "software?fq=resulthostingdatasourceid exact "+'"'+id+'"'; + } + + if(parameters != "") { + + this._searchSoftwareService.searchSoftwareForDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software for Dataproviders: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResults(keyword:string,refine:boolean, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + parameters += "&"+doisParams; + }else{ + parameters = "q=" + keyword; + } + } + this._getResults(parameters,refine,page,size); +} +private _getResults(parameters:string,refine:boolean, page: number, size: number){ + this.csvParams = parameters; + + // if(!refine && !this.searchPage){ + // this.searchPage = new SearchPageComponent(this._location); + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + //this.searchPage.openLoading(); + this.disableForms = true; + this.results = []; + this.searchUtils.totalResults = 0; + + this.subResults = this._searchSoftwareService.searchSoftware(parameters,(refine)?this.searchPage.getRefineFieldsQuery():null, page, size, this.searchPage.getFields()).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refine){ + this.filters = data[2]; + } + this.searchPage.checkSelectedFilters(this.filters); + this.searchPage.updateBaseUrlWithParameters(this.filters); + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + //this.searchPage.closeLoading(); + this.disableForms = false; + + if(this.searchUtils.status == this.errorCodes.DONE) { + // Page out of limit!!! + let totalPages:any = this.searchUtils.totalResults/(this.searchUtils.size); + if(!(Number.isInteger(totalPages))) { + totalPages = (parseInt(totalPages, 10) + 1); + } + if(totalPages < page) { + this.searchUtils.totalResults = 0; + this.searchUtils.status = this.errorCodes.OUT_OF_BOUND; + } + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + //this.searchPage.closeLoading(); + this.disableForms = false; + } + ); +} + + + + private setFilters(){ + //TODO set filters from + } + + public queryChanged($event) { + this.loadPaging = true; + + var parameters = $event.value; + //this.getResults(parameters, this.searchUtils.page, this.searchUtils.size, "searchPage"); + this._getResults(parameters, true, this.searchUtils.page, this.searchUtils.size); + } +} diff --git a/searchPages/simple/searchSoftware.module.ts b/searchPages/simple/searchSoftware.module.ts new file mode 100644 index 00000000..58d498e6 --- /dev/null +++ b/searchPages/simple/searchSoftware.module.ts @@ -0,0 +1,31 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import{SearchSoftwareComponent} from './searchSoftware.component'; + +import {SearchResultsModule } from '../searchUtils/searchResults.module'; + +import {SoftwareServiceModule} from '../../services/softwareService.module'; +import {SearchFormModule} from '../searchUtils/searchForm.module'; +import {SearchPageModule} from '../searchUtils/searchPage.module'; +import {FreeGuard} from'../../login/freeGuard.guard'; + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + SoftwareServiceModule, + SearchFormModule, SearchResultsModule, SearchPageModule + + ], + declarations: [ + SearchSoftwareComponent + ], + providers:[FreeGuard + ], + exports: [ + SearchSoftwareComponent + ] +}) +export class SearchSoftwareModule { } diff --git a/services/dataProvidersService.module.ts b/services/dataProvidersService.module.ts new file mode 100644 index 00000000..88e7b6df --- /dev/null +++ b/services/dataProvidersService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchDataprovidersService} from './searchDataproviders.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchDataprovidersService +], + exports: [ + ] +}) +export class DataProvidersServiceModule { } diff --git a/services/datasetsService.module.ts b/services/datasetsService.module.ts new file mode 100644 index 00000000..e5298338 --- /dev/null +++ b/services/datasetsService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchDatasetsService} from './searchDatasets.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchDatasetsService +], + exports: [ + ] +}) +export class DatasetsServiceModule { } diff --git a/services/metrics.service.ts b/services/metrics.service.ts new file mode 100644 index 00000000..2408b026 --- /dev/null +++ b/services/metrics.service.ts @@ -0,0 +1,82 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {Metrics} from '../utils/entities/metrics'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import 'rxjs/add/operator/do'; + +@Injectable() +export class MetricsService { + metrics: Metrics; + + constructor(private http: Http ) {} + + getMetrics (id: string, entityType: string):any { + console.info("getMetrics in service"); + //let url = OpenaireProperties. getSearchAPIURLLast() + 'publications/' +id+"?format=json"; + let url = OpenaireProperties.getMetricsAPIURL()+entityType+"/"+id+"/clicks"; + let key = url; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseMetrics(res["downloads"], res["views"], res["total_downloads"], res["total_views"], + res["total_openaire_views"], res["total_openaire_downloads"], res["pageviews"])); + } + + + parseMetrics(downloads: any, views: any, totalDownloads: string, totalViews: string, + totalOpenaireViews: string, totalOpenaireDownloads: string, pageViews: string): any { + this.metrics = new Metrics(); + + this.metrics.totalDownloads = totalDownloads; + this.metrics.totalViews = totalViews; + this.metrics.totalOpenaireViews = totalOpenaireViews; + this.metrics.totalOpenaireDownloads = totalOpenaireDownloads; + this.metrics.pageViews = pageViews; + + this.metrics.infos = new Map(); + + for(let i=0; i res.json()) + .map(res => res['results'][0]) + //.map(res => res[0]['result']['metadata']['oaf:entity']['oaf:organization']) + //.map(res => [res, res['rels']['rel']]) + .map(res => this.parseOrganizationInfo(res)); + + + } +/* + getMetrics (id: string):any { + console.info("getOrganizationMetrics in service"); + //let url = OpenaireProperties. getSearchAPIURLLast() + 'publications/' +id+"?format=json"; + let url = OpenaireProperties.getMetricsAPIURL()+"organizations/"+id+"/clicks"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => res['views']); + } +*/ + 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.log(error); + return Observable.throw(error || 'Server error'); + } + + parseOrganizationInfo (data: any):any { + console.info("parseOrganizationInfo"); + this.organizationInfo = new OrganizationInfo(); + + let organization; + let relations; + + if(data != null) { + organization = data['result']['metadata']['oaf:entity']['oaf:organization']; + relations = data['result']['metadata']['oaf:entity']['oaf:organization']['rels']['rel']; + } else { + return null; + } + + if(organization != null) { + + if(organization.hasOwnProperty("websiteurl")) { + this.organizationInfo.title = {"name": organization.legalshortname, "url": organization.websiteurl}; + } else { + this.organizationInfo.title = {"name": organization.legalshortname, "url": ''}; + } + + this.organizationInfo.name = organization.legalname; + + if(this.organizationInfo.title.name == '') { + this.organizationInfo.title.name = this.organizationInfo.name; + } + + if(organization.hasOwnProperty("country")) { + this.organizationInfo.country = organization['country'].classname; + } + } + +//Comment Parsing Projects info +/* + if(data[1] != null) { + + let counter; + let length = relations.length!=undefined ? relations.length : 1; + + for(let i=0; i(); + } + + if(!this.organizationInfo.projects.has(relation['funding']['funder'].name)) { + this.organizationInfo.projects.set(relation['funding']['funder'].name, + new Array<{ "name": string, "id": string, "code": string, + "acronym": string, "funder": string, "funderId": string, + "fundingStream": string, "fundingLevel1": string, "fundingLevel2": string, + "sc39": string, "startDate": string, "endDate": string }>()); + } + + counter = this.organizationInfo.projects.get(relation['funding']['funder'].name).length; + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter] = + { "name": "", "id": "", "code": "", + "acronym": "", "funder": "", "funderId": "", + "fundingStream": "", "fundingLevel1": "", "fundingLevel2": "", + "sc39": "", "startDate": "", "endDate": "" }; + + //let url = ""; + if(relation['to'].content != null && relation['to'].content != "") { + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['id'] = relation['to'].content; + //url = OpenaireProperties.getsearchLinkToProject()+relation['to'].content; + } + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['name'] = relation.title; + //this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['url'] = url; + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['code'] = relation.code; + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['acronym'] = relation.acronym; + + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['funder'] = relation['funding']['funder'].shortname; + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['funderId'] = relation['funding']['funder'].id; + if(relation['funding'].hasOwnProperty("funding_level_0")) { + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['fundingStream'] = relation['funding']['funding_level_0'].name; + } + if(relation['funding'].hasOwnProperty("funding_level_1")) { + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['fundingLevel1'] = relation['funding']['funding_level_1'].name; + } + if(relation['funding'].hasOwnProperty("funding_level_2")) { + this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['fundingLevel2'] = relation['funding']['funding_level_2'].name; + } + //this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['sc39'] = + //this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['startDate'] = + //this.organizationInfo.projects.get(relation['funding']['funder'].name)[counter]['endDate'] = + } + } + + } + + + } /*else if(relation['to'].class == "isProvidedBy") { + + if(this.organizationInfo.dataProviders == undefined) { + this.organizationInfo.dataProviders = new Array<{ "name": string, "url": string, "type": string, "websiteUrl": string , "organizations": {"name": string, "url": string}[]}>(); + } + + counter = this.organizationInfo.dataProviders.length; + this.organizationInfo.dataProviders[counter] = { "name": "", "url": "", "type": "", "websiteUrl": "", "organizations": [] } + + let url=""; + if(relation['to'].content != null && relation['to'].content != "") { + url = OpenaireProperties.getsearchLinkToDataProvider()+relation['to'].content; + } + this.organizationInfo.dataProviders[counter]['name'] = relation.officialname; + this.organizationInfo.dataProviders[counter]['url'] = url; + if(relation.hasOwnProperty("datasourcetype")) { + this.organizationInfo.dataProviders[counter]['type'] = relation['datasourcetype'].classname; + } + this.organizationInfo.dataProviders[counter]['websiteUrl'] = relation.websiteurl; + }*/ +/* -----> + } + } + } +*/ + return this.organizationInfo; + + } + +} diff --git a/services/organizationService.module.ts b/services/organizationService.module.ts new file mode 100644 index 00000000..ee150c3e --- /dev/null +++ b/services/organizationService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {OrganizationService} from './organization.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + OrganizationService +], + exports: [ + ] +}) +export class OrganizationServiceModule { } diff --git a/services/organizationsService.module.ts b/services/organizationsService.module.ts new file mode 100644 index 00000000..0810f680 --- /dev/null +++ b/services/organizationsService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchOrganizationsService} from './searchOrganizations.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchOrganizationsService +], + exports: [ + ] +}) +export class OrganizationsServiceModule { } diff --git a/services/projectsService.module.ts b/services/projectsService.module.ts new file mode 100644 index 00000000..117f5ca7 --- /dev/null +++ b/services/projectsService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchProjectsService} from './searchProjects.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchProjectsService +], + exports: [ + ] +}) +export class ProjectsServiceModule { } diff --git a/services/publicationsService.module.ts b/services/publicationsService.module.ts new file mode 100644 index 00000000..ab371386 --- /dev/null +++ b/services/publicationsService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {SearchPublicationsService} from './searchPublications.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + SearchPublicationsService +], + exports: [ + ] +}) +export class PublicationsServiceModule { } diff --git a/services/refineFieldResults.service.ts b/services/refineFieldResults.service.ts new file mode 100644 index 00000000..71d3fe50 --- /dev/null +++ b/services/refineFieldResults.service.ts @@ -0,0 +1,66 @@ +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'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../shared/cache.service'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; + +@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 ) {} + getRefineFieldsResultsByEntityName(fields:string[], entityName:string):any{ + let url = OpenaireProperties.getSearchAPIURLForEntity(entityName)+"?format=json&refine=true&page=1&size=0"; + for(var i=0; i < fields.length; i++){ + url += "&fields="+fields[i]; + } + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + + .map(res => [res['meta'].total, RefineResultsUtils.parse(res['refineResults'],fields, entityName)]); + + } + getRefineFieldResultsByFieldName(fieldName:string, entityName:string):any{ + let link = OpenaireProperties.getSearchAPIURLForEntity(entityName)+"?fields="+fieldName + "&format=json"; + return this.getField(link,fieldName) + + } + + getField (link:string,fieldName:string):any{ + let url = link+"&refine=true&page=1&size=0"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => res['refineResults']) + .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 new Blob([res['_body']], { type: 'text/csv' })); + } + getCSVResponse(url: string){ + var headers = new Headers(); + headers.append('responseType', 'arraybuffer'); + return this.http.get(url) + .map(res => res['_body']); + } + downloadHTMLFile(url: string, info: string){ + var headers = new Headers(); + headers.append('responseType', 'arraybuffer'); + return this.http.get(url) + .map(res => this.addInfo(res, info)) + .map(res => new Blob([res['_body']], { type: 'text/html' })) + .do(res => console.log(res)) + } + + addInfo(res:any, info:string) { + /* + var para = res.document.createElement("P"); // Create a

    element + var t = res.document.createTextNode("This is a paragraph"); // Create a text node + para.appendChild(t); // Append the text to

    + res.document.body.appendChild(para); + */ + res['_body'] = info+res['_body']; + return res; + } + + 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.log(error); + return Observable.throw(error || 'Server error'); + } + + +} diff --git a/services/reportsService.module.ts b/services/reportsService.module.ts new file mode 100644 index 00000000..0d637dad --- /dev/null +++ b/services/reportsService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {ReportsService} from './reports.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + ReportsService +], + exports: [ + ] +}) +export class ReportsServiceModule { } diff --git a/services/searchDataproviders.service.ts b/services/searchDataproviders.service.ts new file mode 100644 index 00000000..3f05580a --- /dev/null +++ b/services/searchDataproviders.service.ts @@ -0,0 +1,433 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {SearchResult} from '../utils/entities/searchResult'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../shared/cache.service'; +import {StringUtils} from '../utils/string-utils.class'; +@Injectable() +export class SearchDataprovidersService { + constructor(private http: Http ) {} + + searchDataproviders (params: string, refineParams:string, page: number, size: number, refineFields:string[] ):any { + + let link = OpenaireProperties. getSearchAPIURLLast()+"datasources"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "datasource")]); + } + //((oaftype exact datasource) and(collectedfromdatasourceid exact "openaire____::47ce9e9f4fad46e732cff06419ecaabb")) + advancedSearchDataproviders (params: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact datasource) " + url += "?query="; + if(params!= null && params != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (" + params + ")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results'])]) + } + + searchCompatibleDataprovidersTable ():any { + let size: number = 0; + let url: string= OpenaireProperties.getSearchResourcesAPIURL(); + url += '?query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other) not(datasourcetypeuiid exact "pubsrepository::journal") not(datasourcetypeuiid exact "aggregator::pubsrepository::journals"))'; + url += "&page=0&size=0&format=json"; + + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url).map(res => res.json()) + + .map(res => res['meta'].total); + } + + searchCompatibleDataproviders (params: string,refineParams:string, page: number, size: number, refineFields:string[] ):any { + console.info("in search Compatible Dataproviders service function"); + let url: string = OpenaireProperties.getSearchResourcesAPIURL(); + url += '?query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other) not(datasourcetypeuiid exact "pubsrepository::journal") not(datasourcetypeuiid exact "aggregator::pubsrepository::journals"))'; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "datasource")]); + } + + searchEntityRegistriesTable ():any { + let size: number = 0; + let url: string= OpenaireProperties.getSearchResourcesAPIURL(); + url += "?query=((oaftype exact datasource) and(datasourcetypeuiid = other))"; + url += "&page=0&size=0&format=json"; + + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url).map(res => res.json()) + .map(res => res['meta'].total); + } + + searchEntityRegistries (params: string,refineParams:string, page: number, size: number, refineFields:string[] ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + url += "?query=((oaftype exact datasource) and(datasourcetypeuiid = other))"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "datasource")]); + } + + searchJournalsTable ():any { + let size: number = 0; + let url: string= OpenaireProperties.getSearchResourcesAPIURL(); + url += '?query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) and (datasourcetypeuiid exact "pubsrepository::journal" or datasourcetypeuiid exact "aggregator::pubsrepository::journals" ))'; + url += "&page=0&size=0&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url).map(res => res.json()) + .map(res => res['meta'].total); + } + + searchJournals (params: string,refineParams:string, page: number, size: number, refineFields:string[] ):any { + console.info("in search Journals service function"); + let url: string = OpenaireProperties.getSearchResourcesAPIURL(); + //url += "?query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other))" + url += '?query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) and (datasourcetypeuiid exact "pubsrepository::journal" or datasourcetypeuiid exact "aggregator::pubsrepository::journals" ))'; + + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "datasource")]); + } + + searchDataprovidersForDeposit (id: string,type:string, page: number, size: number):any { + let link = OpenaireProperties.getSearchResourcesAPIURL(); + var compatibilities = ""; + if(type == "Research Data"){ + compatibilities = " and (datasourcecompatibilityid <> UNKNOWN) and (datasourcecompatibilityid = openaire2.0_data)" + }else if(type == "Publications"){ + compatibilities = " and (datasourcecompatibilityid <> UNKNOWN) and (datasourcecompatibilityid <> openaire2.0_data)" + } + let url = link+"?query=(((deletedbyinference = false) AND (oaftype exact datasource)) "+((compatibilities && compatibilities.length > 0)?" "+compatibilities+" ":"")+") and (relorganizationid exact "+id+")"; + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + searchDataProvidersBySubjects(keyword:string, type:string, page: number, size: number):any { + let link = OpenaireProperties.getSearchResourcesAPIURL(); + var compatibilities = ""; + if(type == "Research Data"){ + compatibilities = " and (datasourcecompatibilityid <> UNKNOWN) and (datasourcecompatibilityid = openaire2.0_data)" + }else if(type == "Publications"){ + compatibilities = " and (datasourcecompatibilityid <> UNKNOWN) and (datasourcecompatibilityid <> openaire2.0_data)" + } + let url = link+"?query=(((deletedbyinference = false) AND (oaftype exact datasource)) "+((compatibilities && compatibilities.length > 0)?" "+ + compatibilities+" ":"")+") "+ + " and (datasourcesubject all "+'"'+keyword+'"'+") " ; + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + + } + + getDataProvidersforEntityRegistry(datasourceId: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact datasource) " + url += "?query="; + if(datasourceId!= null && datasourceId != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (collectedfromdatasourceid exact \"" + datasourceId + "\")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + searchDataprovidersForEntity (params: string, page: number, size: number):any { + let link = OpenaireProperties. getSearchAPIURLLast(); + let url = link+params+"/datasources?format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } +/* + searchDataprovidersCSV (params: string, refineParams:string, page: number, size: number):any { + + let link = OpenaireProperties. getSearchAPIURLLast()+"datasources"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => this.parseResultsCSV(res['results'])); + } +*/ +/* + searchEntityRegistriesCSV (params: string,refineParams:string, page: number, size: number):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + url += "?query=((oaftype exact datasource) and(datasourcetypeuiid = other))" + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page - 1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => this.parseResultsCSV(res['results'])); + } +*/ +/* + searchCompatibleDataprovidersCSV (params: string,refineParams:string, page: number, size: number):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + url += "?query=((oaftype exact datasource) not(datasourcecompatibilityid = UNKNOWN) not(datasourcecompatibilityid = notCompatible) not(datasourcetypeuiid = other))" + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page - 1)+"&size="+size+"&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => this.parseResultsCSV(res['results'])); + } +*/ + + + parseResults(data: any): SearchResult[] { + let results: SearchResult[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i = new Set(); + + let relLength = Array.isArray(resData['rels']['rel']) ? resData['rels']['rel'].length : 1; + + for(let i=0; i res.json()) + .map(res => res.total); + } + + numOfEntityDataproviders(id: string, entity: string):any { + var parameters = ""; + if(entity == "organization") { + parameters = "organizations/"+id+"/datasources/count"; + } + + let url = OpenaireProperties.getSearchAPIURLLast()+parameters+"?format=json"; + return this.numOfDataproviders(url); + } + + numOfSearchDataproviders(params: string):any { + let url: string = OpenaireProperties.getSearchAPIURLLast()+"datasources/count?format=json"; + if(params != "") { + url += "&q=" + params; + } + + return this.numOfDataproviders(url); + } +/* + private quote(word: any): string { + return '"'+word+'"'; + } +*/ +} diff --git a/services/searchDatasets.service.ts b/services/searchDatasets.service.ts new file mode 100644 index 00000000..c6aec560 --- /dev/null +++ b/services/searchDatasets.service.ts @@ -0,0 +1,343 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {SearchResult} from '../utils/entities/searchResult'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + +import { ParsingFunctions } from '../landingPages/landing-utils/parsingFunctions.class'; + +@Injectable() +export class SearchDatasetsService { + private sizeOfDescription: number = 270; + public parsingFunctions: ParsingFunctions = new ParsingFunctions(); + + constructor(private http: Http ) {} + + searchDatasets (params: string, refineParams:string, page: number, size: number, refineFields:string[] ):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"datasets"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+ (page-1) +"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "dataset")]); + } + searchDatasetById (id: string ):any { + + let url = OpenaireProperties.getSearchAPIURLLast()+"datasets/"+id+"?format=json"; + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseResults(res)); + } + + searchAggregators (id: string, params: string, refineParams:string, page: number, size: number ):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"datasets"; + + let url = link+"?"+"&format=json"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size; + + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseRefineResults(id, res['refineResults'])) + } + + searchDatasetsByDois (DOIs: string[], refineParams:string, page: number, size: number, refineFields:string[] ):any { + let link = OpenaireProperties.getSearchAPIURLLast()+"datasets"; + let url = link+"?"; + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + url += "&"+doisParams; + + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+ (page-1) +"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "dataset")]); + } + advancedSearchDatasets (params: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact result) and (resulttypeid exact dataset) " + url += "?query="; + if(params!= null && params != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (" + params + ")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + searchDatasetsForEntity (params: string, page: number, size: number):any { + let link = OpenaireProperties.getSearchAPIURLLast(); + let url = link+params+"/datasets"+"?format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + + searchDatasetsForDataproviders(params: string, page: number, size: number):any { + let link = OpenaireProperties.getSearchAPIURLLast(); + let url = link+params+ "&page="+(page-1)+"&size="+size + "&format=json"; + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + + parseResults(data: any): SearchResult[] { + let results: SearchResult[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i(); + result.types = new Array(); + let types = new Set(); + + let counter = 0; + let instance; + + let length = Array.isArray(resData['children']['instance']) ? resData['children']['instance'].length : 1; + + for(let i=0; i(); + } + + result['authors'].push({"name": relation.fullname, "id": relation['to'].content}); + } else */if(relation['to'].class == "isProducedBy") { + result['projects'] = this.parseProjects(result['projects'], relation); + } + } + } + } + + if(resData.hasOwnProperty("creator") && resData['creator'] != null) { + if(result['authors'] == undefined) { + result['authors'] = new Array(); + } + + let authors = resData['creator']; + let length = Array.isArray(authors) ? authors.length : 1; + + for(let i=0; i this.sizeOfDescription) { + result.description = result.description.substring(0, this.sizeOfDescription)+"..."; + } + + result.embargoEndDate = resData.embargoenddate; + + if(!Array.isArray(resData.publisher)) { + result.publisher = resData.publisher; + } else { + for(let i=0; i(); + } + + let countProjects = projects.length; + + projects[countProjects] = { + "id": "", "acronym": "", "title": "", + "funderShortname": "", "funderName": "", + "code": "" + } + + if(relation.title != 'unidentified') { + projects[countProjects]['id'] = + /*OpenaireProperties.getsearchLinkToProject() + */relation['to'].content; + projects[countProjects]['acronym'] = relation.acronym; + projects[countProjects]['title'] = relation.title; + projects[countProjects]['code'] = relation.code; + } else { + projects[countProjects]['id'] = ""; + projects[countProjects]['acronym'] = ""; + projects[countProjects]['title'] = ""; + projects[countProjects]['code'] = ""; + } + + if(relation.hasOwnProperty("funding")) { + let fundingLength = Array.isArray(relation['funding']) ? relation['funding'].length : 1; + + for(let z=0; z res.json()) + .map(res => res.total); + } + + numOfEntityDatasets(id: string, entity: string):any { + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id+"/datasets/count"; + } + + let url = OpenaireProperties.getSearchAPIURLLast()+parameters+"?format=json"; + return this.numOfDatasets(url); + } + + numOfSearchDatasets(params: string):any { + let url = OpenaireProperties.getSearchAPIURLLast()+"datasets/count?format=json"; + if(params != "") { + url += "&q=" + params; + } + return this.numOfDatasets(url); + } +} diff --git a/services/searchOrganizations.service.ts b/services/searchOrganizations.service.ts new file mode 100644 index 00000000..5da21881 --- /dev/null +++ b/services/searchOrganizations.service.ts @@ -0,0 +1,191 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../shared/cache.service'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {SearchResult} from '../utils/entities/searchResult'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; + +@Injectable() +export class SearchOrganizationsService { + + constructor(private http: Http ) {} + + parseResultsForDeposit(data: any): {"name": string, "id": string}[] { + let results: {"name": string, "id": string}[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i res.json()) + //.do(res => console.info(res)) + + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "organization")]); + } + advancedSearchOrganizations (params: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact organization) " + url += "?query="; + if(params!= null && params != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (" + params + ")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + parseResults(data: any): SearchResult[] { + let results: SearchResult[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i(); + } + + let countProjects = result['projects'].length; + + result['projects'][countProjects] = { + "id": "", "acronym": "", "title": "", + "funderShortname": "", "funderName": "", + "code": "" + } + + if(relation.title != 'unidentified') { + result['projects'][countProjects]['id'] = + /*OpenaireProperties.getsearchLinkToProject() + */relation['to'].content; + result['projects'][countProjects]['acronym'] = relation.acronym; + result['projects'][countProjects]['title'] = relation.title; + result['projects'][countProjects]['code'] = relation.code; + } else { + result['projects'][countProjects]['id'] = ""; + result['projects'][countProjects]['acronym'] = ""; + result['projects'][countProjects]['title'] = ""; + result['projects'][countProjects]['code'] = ""; + } + + if(relation.hasOwnProperty("funding")) { + let fundingLength = Array.isArray(relation['funding']) ? relation['funding'].length : 1; + + for(let z=0; z res.json()) + .map(res => res.total); + } + + numOfEntityOrganizations(id: string, entity: string):any { + // currently not used - if used fix entity comparison below + var parameters: string = ""; + if(entity == "organization") { + parameters = "organizations/"+id+"/organizations/count"; + } + + let url = OpenaireProperties.getSearchAPIURLLast()+parameters+"?format=json"; + return this.numOfOrganizations(url); + } + + numOfSearchOrganizations(params: string):any { + let url = OpenaireProperties.getSearchAPIURLLast()+"organizations/count?format=json"; + if(params != "") { + url += "&q=" + params; + } + return this.numOfOrganizations(url); + } +} diff --git a/services/searchProjects.service.ts b/services/searchProjects.service.ts new file mode 100644 index 00000000..741ca621 --- /dev/null +++ b/services/searchProjects.service.ts @@ -0,0 +1,242 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../shared/cache.service'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {SearchResult} from '../utils/entities/searchResult'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; + +@Injectable() +export class SearchProjectsService { + private sizeOfDescription: number = 270; + + constructor(private http: Http ) {} + + searchProjects (params: string, refineParams:string, page: number, size: number, refineFields:string[] ):any { + + console.info("In searchProjects"); + + let link = OpenaireProperties.getSearchAPIURLLast()+"projects"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size + "&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "project")]); + } + getProjectsforDataProvider (datasourceId: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact project) " + url += "?query="; + if(datasourceId!= null && datasourceId != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (collectedfromdatasourceid exact \"" + datasourceId + "\")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + advancedSearchProjects (params: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact project) " + url += "?query="; + if(params!= null && params != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (" + params + ")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + getProjectsForOrganizations (organizationId: string, filterquery: string, page: number, size: number, refineFields:string[] ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact project) " + url += "?query="; + if(filterquery!= null && filterquery != '' ) { + url +="( ( "+basicQuery+ " ) and (relorganizationid exact \"" + organizationId + "\")"+" " + filterquery + ")"; + }else{ + url +=" (( "+basicQuery+ " ) " +" and (relorganizationid exact \"" + organizationId + "\"))"; + } + if(refineFields!= null && refineFields.length > 0 ) { + url +="&refine=true"; + for(let i=0; i< refineFields.length ; i++ ){ + url +="&fields="+refineFields[i]; + } + } + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "project")]); + } + getFunders():any { + let url = OpenaireProperties.getSearchAPIURLLast()+"projects?refine=true&fields=funder&size=0"+ "&format=json";; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, res['refineResults']['funder']]); + + + } + + searchForProjectsObs(keyword:string, funderId:string):any { + let url = 'search?action=search&sTransformer=projects_openaire&query='+ + '%28oaftype+exact+project%29+and+%28%28projecttitle+%3D+%22'+keyword+'%22%29+or+%28projectacronym+%3D+%22'+keyword+'%22%29+or+%28projectcode+%3D+%22'+keyword+'%22%29%29+and+%28funder+exact+'+funderId+'%29&size=10&locale=en_GB&format=json'; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url).toPromise() + .then(request =>{ + return (request.json().response.results)?request.json().response.results.result:request.json().response.result; + + }) ; + } + parseResults(data: any): SearchResult[] { + let results: SearchResult[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i(); + } + + let countOrganizations = result['organizations'].length; + + result['organizations'][countOrganizations] = { "name": "", "id": "" } + + result['organizations'][countOrganizations]['id'] = + /*OpenaireProperties.getsearchLinkToOrganization() + */relation['to'].content; + if(relation.legalshortname) { + result['organizations'][countOrganizations]['name'] = relation.legalshortname; + } else { + result['organizations'][countOrganizations]['name'] = relation.legalname; + } + } + } + } + } + if(resData.hasOwnProperty("fundingtree")) { + if(result['funders'] == undefined) { + result['funders'] = new Array< + {"funderShortname": string, "funderName": string}>(); + } + + let fundingLength = Array.isArray(resData['fundingtree']) ? resData['fundingtree'].length : 1; + + for(let z=0; z res.json()) + .map(res => res.total); + } + + numOfEntityProjects(id: string, entity: string):any { + //let url = OpenaireProperties.getSearchAPIURLLast()+params+(params.indexOf("?") == -1 ?"?":"&")+"format=json"; + var parameters: string = ""; + if(entity == "organization") { + parameters = "organizations/"+id+"/projects/count"; + } + + let url = OpenaireProperties.getSearchAPIURLLast()+parameters+ "?format=json"; + + return this.numOfProjects(url); + } + + numOfSearchProjects(params: string):any { + let url = OpenaireProperties.getSearchAPIURLLast()+"projects/count?format=json"; + if(params != "") { + url += "&q=" + params; + } + return this.numOfProjects(url); + } +} diff --git a/services/searchPublications.service.ts b/services/searchPublications.service.ts new file mode 100644 index 00000000..125f3b84 --- /dev/null +++ b/services/searchPublications.service.ts @@ -0,0 +1,461 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { } from '../shared/cache.service'; + +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {SearchResult} from '../utils/entities/searchResult'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; + +import { ParsingFunctions } from '../landingPages/landing-utils/parsingFunctions.class'; + + +@Injectable() +export class SearchPublicationsService { + private sizeOfDescription: number = 270; + public parsingFunctions: ParsingFunctions = new ParsingFunctions(); + + constructor(private http: Http ) {} + + searchPublications (params: string, refineParams:string, page: number, size: number, refineFields:string[] ):any { + let link = OpenaireProperties.getSearchAPIURLLast()+"publications"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + // .do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "publication")]); + } + searchPublicationById (id: string ):any { + + let url = OpenaireProperties.getSearchAPIURLLast()+"publications/"+id+"?format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseResults(res)); + } + + searchAggregators (id: string, params: string, refineParams:string, page: number, size: number ):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"publications"; + + let url = link+"?"+"&format=json"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size; + + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseRefineResults(id, res['refineResults'])); + } + + searchPublicationsByDois (DOIs: string[], refineParams:string, page: number, size: number, refineFields:string[] ):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"publications"; + + let url = link+"?"+"&format=json&"; + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + url +="&"+doisParams; + + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "publication")]); + } + + advancedSearchPublications (params: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact result) and (resulttypeid exact publication) "; + url += "?query="; + if(params!= null && params != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (" + params + ")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + searchPublicationsForEntity (params: string, page: number, size: number):any { + let link = OpenaireProperties.getSearchAPIURLLast(); + let url = link+params+"/publications"+ "?format=json"; + url += "&page="+(page-1)+"&size="+size; + + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + + searchPublicationsForDataproviders(params: string, page: number, size: number):any { + let link = OpenaireProperties.getSearchAPIURLLast(); + let url = link+params+ "&page="+(page-1)+"&size="+size + "&format=json"; + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } +/* + searchPublicationsCSV (params: string, refineParams:string, page: number, size: number):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"publications"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size+ "&format=json"; + + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + + .map(res => this.parseResultsCSV(res['results'])); + } +*/ + + parseResults(data: any): SearchResult[] { + let results: SearchResult[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i(); + result.types = new Array(); + let types = new Set(); + + let counter = 0; + let instance; + + let length = Array.isArray(resData['children']['instance']) ? resData['children']['instance'].length : 1; + + for(let i=0; i(); + } + + result['authors'].push({"name": relation.fullname, "id": relation['to'].content}); + } else */if(relation['to'].class == "isProducedBy") { + result['projects'] = this.parseProjects(result['projects'], relation); + } + } + } + } + + if(resData.hasOwnProperty("creator") && resData['creator'] != null) { + if(result['authors'] == undefined) { + result['authors'] = new Array(); + } + + let authors = resData['creator']; + let length = Array.isArray(authors) ? authors.length : 1; + + for(let i=0; i this.sizeOfDescription) { + result.description = result.description.substring(0, this.sizeOfDescription) + "..."; + } + + + result.embargoEndDate = resData.embargoenddate; + + results.push(result); + } + + return results; + } + + parseProjects(projects: { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "code": string }[], relation: any ) : { + "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "code": string }[] { + if(projects == undefined) { + projects = new Array< + { "id": string, "acronym": string, "title": string, + "funderShortname": string, "funderName": string, + "code": string + }>(); + } + + let countProjects = projects.length; + + projects[countProjects] = { + "id": "", "acronym": "", "title": "", + "funderShortname": "", "funderName": "", + "code": "" + } + + if(relation.title != 'unidentified') { + projects[countProjects]['id'] = + /*OpenaireProperties.getsearchLinkToProject() + */relation['to'].content; + projects[countProjects]['acronym'] = relation.acronym; + projects[countProjects]['title'] = relation.title; + projects[countProjects]['code'] = relation.code; + } else { + projects[countProjects]['id'] = ""; + projects[countProjects]['acronym'] = ""; + projects[countProjects]['title'] = ""; + projects[countProjects]['code'] = ""; + } + + if(relation.hasOwnProperty("funding")) { + let fundingLength = Array.isArray(relation['funding']) ? relation['funding'].length : 1; + + for(let z=0; z res.json()) + .map(res => res.total); + } + + numOfEntityPublications(id: string, entity: string):any { + var parameters: string = ""; + if(entity == "project") { + parameters = "projects/"+id+"/publications/count"; + } + let url = OpenaireProperties.getSearchAPIURLLast()+parameters+"?format=json"; + return this.numOfPublications(url); + } + + numOfSearchPublications(params: string):any { + let url = OpenaireProperties.getSearchAPIURLLast()+"publications/count?format=json"; + if(params != "") { + url += "&q=" + params; + } + return this.numOfPublications(url); + } +/* + private quote(word: any): string { + return '"'+word+'"'; + } +*/ +} diff --git a/services/searchSoftware.service.ts b/services/searchSoftware.service.ts new file mode 100644 index 00000000..f33c81a1 --- /dev/null +++ b/services/searchSoftware.service.ts @@ -0,0 +1,343 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {OpenaireProperties} from '../utils/properties/openaireProperties'; +import {SearchResult} from '../utils/entities/searchResult'; +import {RefineResultsUtils} from './servicesUtils/refineResults.class'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import { ParsingFunctions } from '../landingPages/landing-utils/parsingFunctions.class'; + +@Injectable() +export class SearchSoftwareService { + private sizeOfDescription: number = 270; + public parsingFunctions: ParsingFunctions = new ParsingFunctions(); + + constructor(private http: Http ) {} + + searchSoftware (params: string, refineParams:string, page: number, size: number, refineFields:string[] ):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"software"; + + let url = link+"?"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+ (page-1) +"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "software")]); + } + searchSoftwareById (id: string ):any { + + let url = OpenaireProperties.getSearchAPIURLLast()+"software/"+id+"?format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseResults(res)); + } + + searchAggregators (id: string, params: string, refineParams:string, page: number, size: number ):any { + + let link = OpenaireProperties.getSearchAPIURLLast()+"software"; + + let url = link+"?"+"&format=json"; + if(params!= null && params != '' ) { + url += params; + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+(page-1)+"&size="+size; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => this.parseRefineResults(id, res['refineResults'])) + } + + searchSoftwareByDois (DOIs: string[], refineParams:string, page: number, size: number, refineFields:string[] ):any { + let link = OpenaireProperties.getSearchAPIURLLast()+"software"; + let url = link+"?"; + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + url += "&"+doisParams; + + } + if(refineParams!= null && refineParams != '' ) { + url += refineParams; + } + url += "&page="+ (page-1) +"&size="+size+"&format=json"; + + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results']),RefineResultsUtils.parse(res['refineResults'],refineFields, "software")]); + } + advancedSearchSoftware (params: string, page: number, size: number ):any { + let url = OpenaireProperties.getSearchResourcesAPIURL(); + var basicQuery = "(oaftype exact result) and (resulttypeid exact software) " + url += "?query="; + if(params!= null && params != '' ) { + url +=" ( "+basicQuery+ " ) " +" and (" + params + ")"; + }else{ + url +=" ( "+basicQuery+ " ) "; + } + + url += "&page="+(page-1)+"&size="+size; + url += "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + //.do(res => console.info(res)) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + searchSoftwareForEntity (params: string, page: number, size: number):any { + let link = OpenaireProperties.getSearchAPIURLLast(); + let url = link+params+"/software"+"?format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + + searchSoftwareForDataproviders(params: string, page: number, size: number):any { + let link = OpenaireProperties.getSearchAPIURLLast(); + let url = link+params+ "&page="+(page-1)+"&size="+size + "&format=json"; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()) + .map(res => [res['meta'].total, this.parseResults(res['results'])]); + } + + parseResults(data: any): SearchResult[] { + let results: SearchResult[] = []; + + let length = Array.isArray(data) ? data.length : 1; + + for(let i=0; i(); + result.types = new Array(); + let types = new Set(); + + let counter = 0; + let instance; + + let length = Array.isArray(resData['children']['instance']) ? resData['children']['instance'].length : 1; + + for(let i=0; i(); + } + + result['authors'].push({"name": relation.fullname, "id": relation['to'].content}); + } else */if(relation['to'].class == "isProducedBy") { + result['projects'] = this.parseProjects(result['projects'], relation); + } + } + } + } + + if(resData.hasOwnProperty("creator") && resData['creator'] != null) { + if(result['authors'] == undefined) { + result['authors'] = new Array(); + } + + let authors = resData['creator']; + let length = Array.isArray(authors) ? authors.length : 1; + + for(let i=0; i this.sizeOfDescription) { + result.description = result.description.substring(0, this.sizeOfDescription)+"..."; + } + + result.embargoEndDate = resData.embargoenddate; + + if(!Array.isArray(resData.publisher)) { + result.publisher = resData.publisher; + } else { + for(let i=0; i(); + } + + let countProjects = projects.length; + + projects[countProjects] = { + "id": "", "acronym": "", "title": "", + "funderShortname": "", "funderName": "", + "code": "" + } + + if(relation.title != 'unidentified') { + projects[countProjects]['id'] = + /*OpenaireProperties.getsearchLinkToProject() + */relation['to'].content; + projects[countProjects]['acronym'] = relation.acronym; + projects[countProjects]['title'] = relation.title; + projects[countProjects]['code'] = relation.code; + } else { + projects[countProjects]['id'] = ""; + projects[countProjects]['acronym'] = ""; + projects[countProjects]['title'] = ""; + projects[countProjects]['code'] = ""; + } + + if(relation.hasOwnProperty("funding")) { + let fundingLength = Array.isArray(relation['funding']) ? relation['funding'].length : 1; + + for(let z=0; z res.json()) + .map(res => res.total); + } + + numOfEntitySoftware(id: string, entity: string):any { + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id+"/software/count"; + } + + let url = OpenaireProperties.getSearchAPIURLLast()+parameters+"?format=json"; + return this.numOfSoftware(url); + } + + numOfSearchSoftware(params: string):any { + let url = OpenaireProperties.getSearchAPIURLLast()+"software/count?format=json"; + if(params != "") { + url += "&q=" + params; + } + return this.numOfSoftware(url); + } +} diff --git a/services/servicesUtils/refineResults.class.ts b/services/servicesUtils/refineResults.class.ts new file mode 100644 index 00000000..19cf28d1 --- /dev/null +++ b/services/servicesUtils/refineResults.class.ts @@ -0,0 +1,62 @@ + +import { Filter, Value} from '../../searchPages/searchUtils/searchHelperClasses.class'; +import { SearchFields, FieldDetails} from '../../utils/properties/searchFields'; + + +export class RefineResultsUtils { + + + public static parse (data, fields:string[], entityType:string):Filter[] { + // var data = this.json.refineReuslts; + + var searchFields:SearchFields = new SearchFields(); + var filters:Filter[] = []; + if(data){ + for(let j=0; j +

    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + European Commission +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + OpenAIRE +
    + +
    + +
    +
    +
    +
    +
    +
    diff --git a/sharedComponents/bottom.component.ts b/sharedComponents/bottom.component.ts new file mode 100644 index 00000000..3ae13c03 --- /dev/null +++ b/sharedComponents/bottom.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; +import 'rxjs/Rx'; + +@Component({ + selector: 'bottom', + templateUrl: 'bottom.component.html' +}) +export class BottomComponent { + +} diff --git a/sharedComponents/cookie-law/cookie-law.component.ts b/sharedComponents/cookie-law/cookie-law.component.ts new file mode 100644 index 00000000..3a72e7d0 --- /dev/null +++ b/sharedComponents/cookie-law/cookie-law.component.ts @@ -0,0 +1,148 @@ +/** + * angular2-cookie-law + * + * Copyright 2016-2017, @andreasonny83, All rights reserved. + * + * @author: @andreasonny83 + */ + +import { + Component, + OnInit, + ViewEncapsulation, + HostBinding, + Input, + Output, + EventEmitter, + animate, + state, + trigger, + style, + transition, + AnimationTransitionEvent, +} from '@angular/core'; + +import { + DomSanitizer, + SafeHtml, +} from '@angular/platform-browser'; + +import { + CookieLawService, +} from './cookie-law.service'; + +// import { +// closeIcon, +// } from './icons'; + +export type CookieLawPosition = 'top' | 'bottom'; +export type CookieLawAnimation = 'topIn' | 'bottomIn' | 'topOut' | 'bottomOut'; +export type CookieLawTarget = '_blank' | '_self'; + +@Component({ + selector: 'cookie-law', + // encapsulation: ViewEncapsulation.None, + animations: [ + trigger('state', [ + state('bottomOut', style({ transform: 'translateY(100%)' })), + state('topOut', style({ transform: 'translateY(-100%)' })), + state('*', style({ transform: 'translateY(0)' })), + + transition('void => topIn', [ + style({ transform: 'translateY(-100%)' }), + animate('1000ms ease-in-out'), + ]), + + transition('void => bottomIn', [ + style({ transform: 'translateY(100%)' }), + animate('1000ms ease-in-out'), + ]), + + transition('* => *', animate('1000ms ease-out')), + ]) + ], + styleUrls: [ './cookie-law.css' ], + templateUrl: './cookie-law.html', +}) +export class CookieLawComponent implements OnInit { + public cookieLawSeen: boolean; + + @Input('learnMore') + get learnMore() { return this._learnMore; } + set learnMore(value: string) { + this._learnMore = (value !== null && `${value}` !== 'false') ? value : null; + } + + @Input('target') + get target() { return this._target; } + set target(value: CookieLawTarget) { + this._target = (value !== null && `${value}` !== 'false' && + (`${value}` === '_blank' || `${value}` === '_self') + ) ? value : '_blank'; + } + + @Input('position') + get position() { return this._position; } + set position(value: CookieLawPosition) { + this._position = (value !== null && `${value}` !== 'false' && + (`${value}` === 'top' || `${value}` === 'bottom') + ) ? value : 'bottom'; + } + + @Output('isSeen') + private isSeenEvt: EventEmitter; + + @HostBinding('attr.seen') + public isSeen: boolean; + + private animation: CookieLawAnimation; + private closeSvg: SafeHtml; + private currentStyles: {}; + private _learnMore: string; + private _target: CookieLawTarget; + private _position: CookieLawPosition; + + constructor( + private _service: CookieLawService, + private domSanitizer: DomSanitizer, + ) { + this.isSeenEvt = new EventEmitter(); + this.animation = 'topIn'; + this._position = 'bottom'; + this.cookieLawSeen = this._service.seen(); + } + + ngOnInit(): void { + if (typeof document !== 'undefined') { + this.animation = this.position === 'bottom' ? 'bottomIn' : 'topIn'; + + this.closeSvg = ' ' ; + + if (this.cookieLawSeen) { + this.isSeen = true; + } + + this.currentStyles = { + 'top': this.position === 'top' ? '0' : null, + 'bottom': this.position === 'top' ? 'initial' : null, + }; + } + } + + afterDismissAnimation(evt: AnimationTransitionEvent) { + if (evt.toState === 'topOut' || + evt.toState === 'bottomOut') { + this.isSeen = true; + this.isSeenEvt.emit(this.isSeen); + } + } + + public dismiss(evt?: MouseEvent): void { + if (evt) { + evt.preventDefault(); + } + + this._service.storeCookie(); + this.animation = this.position === 'top' ? 'topOut' : 'bottomOut'; + } +} diff --git a/sharedComponents/cookie-law/cookie-law.css b/sharedComponents/cookie-law/cookie-law.css new file mode 100644 index 00000000..17e09689 --- /dev/null +++ b/sharedComponents/cookie-law/cookie-law.css @@ -0,0 +1,77 @@ +.cookie-law-wrapper a { + color: #bbb; + -webkit-transition: color .2s; + transition: color .2s; +} +.cookie-law-wrapper a:hover { + color: #fff; +} +.cookie-law-wrapper a:hover svg { + fill: #fff; +} +.cookie-law-wrapper { + background: #333; + color: #bbb; + display: block; + /*font-family: Helvetica Neue,Helvetica,Arial,sans-serif; + font-size: 15px; + font-weight: 200; + line-height: 20px;*/ + position: fixed; + bottom: 0; + left: 0; + width: 100%; + z-index: 999999999; + font-smooth: always; + -webkit-font-smoothing: antialiased; + text-align: center; +} +.dismiss { + display: block; + box-sizing: border-box; + padding: 10px; + position: absolute; + top: 0; + right: 10px; + text-decoration: none; + line-height: 20px; +} +.dismiss svg { + display: block; + fill: #bbb; + width: 20px; + height: 20px; + -webkit-transition: fill .2s; + transition: fill .2s; +} +.copy { + box-sizing: border-box; + padding: 10px 60px 10px 10px; +} +.copy span { + color: #fff; + /*font-weight: 400;*/ +} +.copy a { + text-decoration: underline; +} +.copy a:active, .copy a:hover { + outline: 0; +} + +@media (min-width: 600px) { + /* For bigger devices: */ + .copy { + padding: 20px 60px 20px 20px; + /*font-size: 18px; + line-height: 24px;*/ + } + .dismiss { + top: 10px; + right: 15px; + } + .dismiss svg { + width: 24px; + height: 24px; + } +} diff --git a/sharedComponents/cookie-law/cookie-law.html b/sharedComponents/cookie-law/cookie-law.html new file mode 100644 index 00000000..ccccbba4 --- /dev/null +++ b/sharedComponents/cookie-law/cookie-law.html @@ -0,0 +1,23 @@ + + + + + + + ` + }) + + export class ErrorMessagesComponent { + @Input() status: Array; + @Input() type: string; + + public errorCodes:ErrorCodes; + + constructor () {} + + ngOnInit() { + this.errorCodes = new ErrorCodes(); + console.info("ngOnInit"); + if(!this.status) { + this.status = [this.errorCodes.LOADING]; + } + } + + ngOnDestroy() {} + + public checkErroCode(code: number) { + return function(status: number) { + return (status == code); + } + } + } diff --git a/utils/errorMessages.module.ts b/utils/errorMessages.module.ts new file mode 100644 index 00000000..9f7315af --- /dev/null +++ b/utils/errorMessages.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {ErrorMessagesComponent} from './errorMessages.component'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ErrorMessagesComponent + ], + exports: [ + ErrorMessagesComponent + ] +}) +export class ErrorMessagesModule { } diff --git a/utils/exportCSV.class.ts b/utils/exportCSV.class.ts new file mode 100644 index 00000000..c5e39a33 --- /dev/null +++ b/utils/exportCSV.class.ts @@ -0,0 +1,131 @@ + + + +export class ExportCSVComponent { + stockData : any = + { + "columnNames": + ["Symbol", "Company", "Price"], + "export": +/* + [ + { + Symbol: "AAPL", + Company: "Apple Inc.", + Price: "132.54" + }, + { + Symbol: "INTC", + Company: "Intel Corporation", + Price: "33.45" + }, + { + Symbol: "GOOG", + Company: "Google Inc", + Price: "554.52" + }, + ], +*/ + + [ + [ + "AAPL", + "Apple Inc.", + "132.54" + ], + [ + "INTC", + "Intel Corporation", + "33.45" + ], + [ + "GOOG", + "Google Inc", + "554.52" + ], + ], + + + "columnDelimiter": ',', + "lineDelimiter": '\n' + }; + + data: any = this.stockData; + filename: string; + linkname: string = "Download CSV"; + + constructor () { + } + + ngOnInit() { + } + + public static convertArrayOfObjectsToCSV(args) { + console.info("convertArrayOfObjectsToCSV"); + + var result, ctr, keys, columnDelimiter, lineDelimiter, data; + + data = args.export || null; + + if (data == null || !data.length) { + return null; + } + + columnDelimiter = args.columnDelimiter || ','; + lineDelimiter = args.lineDelimiter || '\n'; + + //keys = Object.keys(data[0]); + keys = args.columnNames; + + result = ''; + result += keys.join(columnDelimiter); + result += lineDelimiter; +/* + data.forEach(function(item) { + ctr = 0; + keys.forEach(function(key) { + if (ctr > 0) result += columnDelimiter; + result += item[key]; + ctr++; + }); + result += lineDelimiter; + }); +*/ + + for(let line of data) { + ctr = 0; + for(let column of line) { + if (ctr > 0) result += columnDelimiter; + result += column; + ctr++; + } + result += lineDelimiter; + } + + return result; + } + + public static downloadCSV(data: any, filenameArg: string) { + console.info("downloadCSV"); + + var encodedData, filename, link; + + var csv = this.convertArrayOfObjectsToCSV(data); + if (csv == null) return; + + filename = filenameArg || 'export.csv'; + + if (!csv.match(/^data:text\/csv/i)) { + csv = 'data:text/csv;charset=utf-8,' + csv; + } + encodedData = encodeURI(csv); + + //link = document.createElement('a'); + link = document.getElementsByTagName('a'); + link[0].setAttribute('href', encodedData); + link[0].setAttribute('download', filename); + //document.body.appendChild(link); + link[0].click(); + //document.body.removeChild(link); + } +} diff --git a/utils/fetchEntitiesClasses/fetchDataproviders.class.ts b/utils/fetchEntitiesClasses/fetchDataproviders.class.ts new file mode 100644 index 00000000..1ef9125c --- /dev/null +++ b/utils/fetchEntitiesClasses/fetchDataproviders.class.ts @@ -0,0 +1,291 @@ +import {SearchDataprovidersService} from '../../services/searchDataproviders.service'; +import { ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; + +export class FetchDataproviders { + private errorCodes: ErrorCodes; + + public results =[]; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; public subResults: any; + public CSV: any = { "columnNames": [ "Title", "Type", "Coutries", "Compatibility" ], + "export":[] + }; + public CSVDownloaded = false; + public csvParams: string; + + + constructor ( private _searchDataprovidersService: SearchDataprovidersService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + } + + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + public getResultsByKeyword(keyword:string, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + parameters = "q=" + keyword; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + + this.subResults = this._searchDataprovidersService.searchDataproviders(parameters,null, page, size,[]).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Content Providers: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //ar errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + public getNumForEntity(entity: string, id:string) { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + if(id != "" && entity != "") { + + this._searchDataprovidersService.numOfEntityDataproviders(id, entity).subscribe( + data => { + this.searchUtils.totalResults = data; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + } + + public getNumForSearch(keyword: string) { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this._searchDataprovidersService.numOfSearchDataproviders(keyword).subscribe( + data => { + this.searchUtils.totalResults = data; + this.searchUtils.status = this.errorCodes.DONE; + + if(this.searchUtils.totalResults == 0) { + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + +public getResultsForDeposit(id:string, type:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + if(id != "") { + + this._searchDataprovidersService.searchDataprovidersForDeposit(id,type, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders forDeposit: [id:"+id+", type:"+type+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} +public getResultsBySubjectsForDeposit(subject:string, type:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + this._searchDataprovidersService.searchDataProvidersBySubjects(subject,type, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders forDeposit: [subject:"+subject+", type:"+type+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + +} + public getResultsForEntity(entity:string, id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters = ""; + + if(entity == "organization") { + parameters = "organizations/"+id; + } + + if(parameters != "") { + + this._searchDataprovidersService.searchDataprovidersForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + } + + public getResultsForDataproviders(id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this._searchDataprovidersService.getDataProvidersforEntityRegistry(id, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Dataproviders for Entity Registry: [Id:"+id+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} diff --git a/utils/fetchEntitiesClasses/fetchDatasets.class.ts b/utils/fetchEntitiesClasses/fetchDatasets.class.ts new file mode 100644 index 00000000..9e6916b6 --- /dev/null +++ b/utils/fetchEntitiesClasses/fetchDatasets.class.ts @@ -0,0 +1,253 @@ +import {SearchDatasetsService} from '../../services/searchDatasets.service'; +import { ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; +import {DOI} from '../../utils/string-utils.class'; +import {Subject} from 'rxjs/Subject'; + +export class FetchDatasets{ + private errorCodes: ErrorCodes; + + public results =[]; + public requestComplete: Subject; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + private sub: any; + private subResults: any; + + public csvParams: string; + + constructor ( private _searchDatasetsService: SearchDatasetsService ) { + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.requestComplete = new Subject(); + } + + + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + + public getResultsByKeyword(keyword:string, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + parameters += "&"+doisParams; + }else{ + parameters = "q=" + keyword; + } + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchDatasetsService.searchDatasets(parameters,null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + +public getNumForEntity(entity:string, id:string){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + + if(id != "" && entity != "") { + this._searchDatasetsService.numOfEntityDatasets(id, entity).subscribe( + data => { + this.searchUtils.totalResults = data; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForEntity(entity:string, id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id; + } + + if(parameters != "") { + + this._searchDatasetsService.searchDatasetsForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForDataproviders(id:string, resultsFrom:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters; + if(resultsFrom == "collectedFrom") { + parameters = "datasets?fq=collectedfromdatasourceid exact "+'"'+id+'"'; + } else if(resultsFrom == "hostedBy") { + parameters = "datasets?fq=resulthostingdatasourceid exact "+'"'+id+'"'; + } + + if(parameters != "") { + + this._searchDatasetsService.searchDatasetsForDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Research Data for Dataproviders: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getAggregatorResults(id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchDatasetsService.searchAggregators(id, '&fq=collectedfromdatasourceid exact "'+id+'"',"&refine=true&fields=resulthostingdatasource" , page, size).subscribe( + data => { + this.results = data; + this.searchUtils.totalResults = this.results.length; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + + this.requestComplete.complete(); + }, + err => { + console.log(err); + console.info("status: "+err.status); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + this.requestComplete.complete(); + } + ); +} + +} diff --git a/utils/fetchEntitiesClasses/fetchOrganizations.class.ts b/utils/fetchEntitiesClasses/fetchOrganizations.class.ts new file mode 100644 index 00000000..07cb4c61 --- /dev/null +++ b/utils/fetchEntitiesClasses/fetchOrganizations.class.ts @@ -0,0 +1,76 @@ + import {SearchOrganizationsService} from '../../services/searchOrganizations.service'; + import { ErrorCodes} from '../../utils/properties/openaireProperties'; + import {SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; + +export class FetchOrganizations { + private errorCodes: ErrorCodes; + + public results =[]; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + public sub: any; + public subResults: any; + + + + constructor ( private _searchOrganizationsService: SearchOrganizationsService ) { + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + } + + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + + public getResultsByKeyword(keyword:string , page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + parameters = "q=" + keyword; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchOrganizationsService.searchOrganizations(parameters, null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Organizations: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + +} diff --git a/utils/fetchEntitiesClasses/fetchProjects.class.ts b/utils/fetchEntitiesClasses/fetchProjects.class.ts new file mode 100644 index 00000000..d31a3232 --- /dev/null +++ b/utils/fetchEntitiesClasses/fetchProjects.class.ts @@ -0,0 +1,209 @@ +import {SearchProjectsService} from '../../services/searchProjects.service'; +import {ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; + +export class FetchProjects{ + private errorCodes: ErrorCodes; + + public results =[]; + + public filters; // for getResultsForOrganizations + public funders:any = []; // for getResultsForOrganizations // this is filled with the initial query - before filtering + + public sub: any; + public subResults: any; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + + + constructor (private _searchProjectsService: SearchProjectsService) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + } + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + public getResultsByKeyword(keyword:string, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + parameters = "q=" + keyword; + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchProjectsService.searchProjects(parameters, null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Projects: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + public getResultsForDataproviders(id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this._searchProjectsService.getProjectsforDataProvider(id, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Projects for Dataproviders: [Id:"+id+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + public getNumForEntity(entity: string, id:string) { + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + if(id != "" && entity != "") { + + this._searchProjectsService.numOfEntityProjects(id, entity).subscribe( + data => { + this.searchUtils.totalResults = data; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + } + + public getResultsForOrganizations(organizationId:string, filterquery:string, page: number, size: number, refineFields:string[]){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this._searchProjectsService.getProjectsForOrganizations(organizationId,filterquery, page, size,refineFields).subscribe( + data => { + this.searchUtils.totalResults = data[0]; // the results can be filtered so this number can be no total results + console.info("search Projects for Organization: [Id:"+organizationId+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + if(refineFields && refineFields.length > 0){ + this.filters = data[2]; + filterquery = decodeURIComponent(filterquery); + for(var i = 0; i < this.filters.length; i++){ + if(filterquery.indexOf(this.filters[i].filterId) !== -1){ + console.log("this.filters[i].filterId:"+this.filters[i].filterId); + for(var j = 0; j < this.filters[i].values.length; j++){ + console.log("this.filters[i].values[j].id:"+this.filters[i].values[j].id); + if(filterquery.indexOf(this.filters[i].values[j].id) !== -1){ + this.filters[i].values[j].selected = true; + } + } + } + } + } + + if(filterquery == ""){ + this.searchUtils.totalResultsNoFilters = this.searchUtils.totalResults; + this.funders = []; + for(var i = 0; i < this.filters.length; i++){ + console.log("this.filters[i].filterId:"+this.filters[i].filterId); + if(this.filters[i].filterId == "funder"){ + this.funders = (this.filters[i].values); + + } + } + console.log(" this.funders:"+ this.funders); + + } + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + + +} diff --git a/utils/fetchEntitiesClasses/fetchPublications.class.ts b/utils/fetchEntitiesClasses/fetchPublications.class.ts new file mode 100644 index 00000000..c2993f70 --- /dev/null +++ b/utils/fetchEntitiesClasses/fetchPublications.class.ts @@ -0,0 +1,233 @@ + +import {SearchPublicationsService} from '../../services/searchPublications.service'; +import {ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchFields, FieldDetails} from '../../utils/properties/searchFields'; + import {SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; +import {DOI} from '../../utils/string-utils.class'; +import {Subject} from 'rxjs/Subject'; + +export class FetchPublications { + private errorCodes: ErrorCodes; + + public results =[]; + + public requestComplete: Subject; + + // public filters =[]; + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + // public baseUrl:string = ""; + public sub: any; + public subResults: any; + public searchFields:SearchFields = new SearchFields(); + // public refineFields: string[] = this.searchFields.RESULT_REFINE_FIELDS; + // public fieldIdsMap=this.searchFields.RESULT_FIELDS; + //: { [key:string] :{ name:string, operator:string, type:string, indexField:string, equalityOperator:string }} = this.searchFields.PUBLICATION_FIELDS_MAP; + + public CSV: any = { "columnNames": ["Title", "Authors", "Publication Year", "DOI", + /*"Download From", "Publication type", "Journal",*/ + "Funder", "Project Name (GA Number)", "Access"], + "export":[] + }; + public CSVDownloaded = false; + public csvParams: string; + + constructor ( private _searchPublicationsService: SearchPublicationsService ) { + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + // this.baseUrl = OpenaireProperties.getLinkToSearchPublications(); + + this.requestComplete = new Subject(); + } + + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + public getResultsByKeyword(keyword:string, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + parameters += "&"+doisParams; + }else{ + parameters = "q=" + keyword; + } + } + + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchPublicationsService.searchPublications(parameters,null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Publications: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + +public getResultsForEntity(entity:string, id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters = ""; + if(entity == "project") { + parameters = "projects/"+id; + } else if(entity == "organization") { + parameters = "organizations/"+id; + } + + if(parameters != "") { + this._searchPublicationsService.searchPublicationsForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + + console.info("search Publications for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForDataproviders(id:string, resultsFrom:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters; + if(resultsFrom == "collectedFrom") { + parameters = "publications?fq=collectedfromdatasourceid exact "+'"'+id+'"'; + } else if(resultsFrom == "hostedBy") { + parameters = "publications?fq=resulthostingdatasourceid exact "+'"'+id+'"'; + } + + if(parameters != "") { + + this._searchPublicationsService.searchPublicationsForDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Publications for Dataproviders: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getAggregatorResults(id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchPublicationsService.searchAggregators(id, '&fq=collectedfromdatasourceid exact "'+id+'"',"&refine=true&fields=resulthostingdatasource" , page, size).subscribe( + data => { + this.results = data; + this.searchUtils.totalResults = this.results.length; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + + this.requestComplete.complete(); + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + this.requestComplete.complete(); + } + ); +} + + +} diff --git a/utils/fetchEntitiesClasses/fetchSoftware.class.ts b/utils/fetchEntitiesClasses/fetchSoftware.class.ts new file mode 100644 index 00000000..9dbc37d6 --- /dev/null +++ b/utils/fetchEntitiesClasses/fetchSoftware.class.ts @@ -0,0 +1,253 @@ +import {SearchSoftwareService} from '../../services/searchSoftware.service'; +import { ErrorCodes} from '../../utils/properties/openaireProperties'; +import {SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; +import {DOI} from '../../utils/string-utils.class'; +import {Subject} from 'rxjs/Subject'; + +export class FetchSoftware{ + private errorCodes: ErrorCodes; + + public results =[]; + public requestComplete: Subject; + + public searchUtils:SearchUtilsClass = new SearchUtilsClass(); + private sub: any; + private subResults: any; + + public csvParams: string; + + constructor ( private _searchSoftwareService: SearchSoftwareService ) { + + this.errorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.requestComplete = new Subject(); + } + + + + public ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + if(this.subResults){ + this.subResults.unsubscribe(); + } + } + + + public getResultsByKeyword(keyword:string, page: number, size: number){ + var parameters = ""; + if(keyword.length > 0){ + var DOIs:string[] = DOI.getDOIsFromString(keyword); + var doisParams = ""; + + for(var i =0 ;i < DOIs.length; i++){ + doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"'; + } + if(doisParams.length > 0){ + parameters += "&"+doisParams; + }else{ + parameters = "q=" + keyword; + } + } + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchSoftwareService.searchSoftware(parameters,null, page, size, []).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } + +public getNumForEntity(entity:string, id:string){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + + if(id != "" && entity != "") { + this._searchSoftwareService.numOfEntitySoftware(id, entity).subscribe( + data => { + this.searchUtils.totalResults = data; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForEntity(entity:string, id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters = ""; + + if(entity == "project") { + parameters = "projects/"+id; + } + + if(parameters != "") { + + this._searchSoftwareService.searchSoftwareForEntity(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software for "+entity+": [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getResultsForDataproviders(id:string, resultsFrom:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + var parameters; + if(resultsFrom == "collectedFrom") { + parameters = "software?fq=collectedfromdatasourceid exact "+'"'+id+'"'; + } else if(resultsFrom == "hostedBy") { + parameters = "software?fq=resulthostingdatasourceid exact "+'"'+id+'"'; + } + + if(parameters != "") { + + this._searchSoftwareService.searchSoftwareForDataproviders(parameters, page, size).subscribe( + data => { + this.searchUtils.totalResults = data[0]; + console.info("search Software for Dataproviders: [Parameters:"+parameters+" ] [total results:"+this.searchUtils.totalResults+"]"); + this.results = data[1]; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + }, + err => { + console.log(err); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + } + ); + } +} + +public getAggregatorResults(id:string, page: number, size: number){ + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.LOADING; + + this.subResults = this._searchSoftwareService.searchAggregators(id, '&fq=collectedfromdatasourceid exact "'+id+'"',"&refine=true&fields=resulthostingdatasource" , page, size).subscribe( + data => { + this.results = data; + this.searchUtils.totalResults = this.results.length; + + //var errorCodes:ErrorCodes = new ErrorCodes(); + this.searchUtils.status = this.errorCodes.DONE; + if(this.searchUtils.totalResults == 0 ){ + this.searchUtils.status = this.errorCodes.NONE; + } + + this.requestComplete.complete(); + }, + err => { + console.log(err); + console.info("status: "+err.status); + //TODO check erros (service not available, bad request) + // if( ){ + // this.searchUtils.status = ErrorCodes.ERROR; + // } + //var errorCodes:ErrorCodes = new ErrorCodes(); + //this.searchUtils.status = errorCodes.ERROR; + if(err.status == '404') { + this.searchUtils.status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.searchUtils.status = this.errorCodes.ERROR; + } else { + this.searchUtils.status = this.errorCodes.NOT_AVAILABLE; + } + + this.requestComplete.complete(); + } + ); +} + +} diff --git a/utils/helper/helper.component.ts b/utils/helper/helper.component.ts new file mode 100644 index 00000000..66c3c70c --- /dev/null +++ b/utils/helper/helper.component.ts @@ -0,0 +1,47 @@ +import { Component, Input } from '@angular/core'; +import 'rxjs/Rx'; +import {HelperService} from './helper.service'; +import {OpenaireProperties} from '../properties/openaireProperties'; + +@Component({ + selector: 'helper', + template: ` +
    +
    +
    +
    +` +}) +export class HelperComponent { + texts=[]; + @Input() style:boolean = false; + @Input() position:string = 'right'; + @Input() styleName:string = ''; + sub:any; + + constructor ( + private _service: HelperService + ) { + } + + ngOnInit() { + if(OpenaireProperties.isHelperEnabled() && location){ + this.sub = this._service.getHelper(location.pathname).subscribe( + data => { + this.texts =(data && data.content && data.content[this.position] )? data.content[this.position]:[]; + }, + err => { + console.log(err); + + } + ); + } + } + ngOnDestroy() { + if(this.sub){ + this.sub.unsubscribe(); + } + } + + +} diff --git a/utils/helper/helper.module.ts b/utils/helper/helper.module.ts new file mode 100644 index 00000000..93752d19 --- /dev/null +++ b/utils/helper/helper.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +// import { RouterModule } from "@angular/router"; + +import {HelperComponent} from './helper.component'; +// import {HelperServiceModule} from './helperService.module'; +import {HelperService} from './helper.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule, + // RouterModule//,HelperServiceModule + ], + declarations: [ + HelperComponent + ], + providers:[HelperService], + exports: [ + HelperComponent + ] +}) +export class HelperModule{ } diff --git a/utils/helper/helper.service.ts b/utils/helper/helper.service.ts new file mode 100644 index 00000000..013ad903 --- /dev/null +++ b/utils/helper/helper.service.ts @@ -0,0 +1,26 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + +import { OpenaireProperties } from '../../utils/properties/openaireProperties'; + +@Injectable() +export class HelperService { + constructor(private http: Http ) {} + + getHelper (router: string):any { + console.info("get router helpText for : "+router); + + let url = OpenaireProperties.getHelperPageUrl() + '?q=' + router; + + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .map(res => res.json()); + + } + + + +} diff --git a/utils/helper/helperService.module.ts b/utils/helper/helperService.module.ts new file mode 100644 index 00000000..475fd82d --- /dev/null +++ b/utils/helper/helperService.module.ts @@ -0,0 +1,20 @@ +import { NgModule} from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {HelperService} from './helper.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + ], + providers:[ + HelperService +], + exports: [ + ] +}) +export class HelperServiceModule { } diff --git a/utils/iframe.component.ts b/utils/iframe.component.ts new file mode 100644 index 00000000..302f6431 --- /dev/null +++ b/utils/iframe.component.ts @@ -0,0 +1,21 @@ +import {Component, ElementRef, Input} from '@angular/core'; +import { SafeResourceUrl, DomSanitizer } from '@angular/platform-browser'; +//Usage :: ` +@Component({ + selector: 'i-frame', + template: ` + + ` +}) +export class IFrameComponent { + public safeUrl: SafeResourceUrl; + @Input() url ; + @Input() width = '100%'; + @Input() height = '300'; + constructor(private sanitizer: DomSanitizer) { + } + ngOnInit() { + this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.url); + console.info("URL:" + this.safeUrl); + } +} diff --git a/utils/iframe.module.ts b/utils/iframe.module.ts new file mode 100644 index 00000000..702e5ab5 --- /dev/null +++ b/utils/iframe.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {IFrameComponent} from './iframe.component'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule + ], + declarations: [ + IFrameComponent + ], + exports: [ + IFrameComponent + ] +}) +export class IFrameModule { } diff --git a/utils/metaTags/openaireMetaTags.class.ts b/utils/metaTags/openaireMetaTags.class.ts new file mode 100644 index 00000000..3b78aa42 --- /dev/null +++ b/utils/metaTags/openaireMetaTags.class.ts @@ -0,0 +1,21 @@ +import {Meta} from '../../../angular2-meta'; + +export class OpenaireMetaTags{ + + constructor (private _meta: Meta ) { + } + + updateDescription(description:string){ + this._meta.updateMeta("description", description); + this._meta.updateProperty("og:description", description); + } + updateTitle(title:string){ + var _prefix ="OpenAIRE | "; + var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title); + this._meta.setTitle(_title ); + this._meta.updateProperty("og:title",_title); + } + updateUrl(url:string){ + this._meta.updateProperty("og:url", url); + } +} diff --git a/utils/modal/alert.ts b/utils/modal/alert.ts new file mode 100644 index 00000000..c7155cd8 --- /dev/null +++ b/utils/modal/alert.ts @@ -0,0 +1,111 @@ +import {Component, ViewEncapsulation, ComponentRef, ElementRef, Input, EventEmitter, Output} from '@angular/core'; +// import { DynamicComponentLoader} from '@angular/core'; + +import {Open} from './open.component'; + +@Component({ + selector: 'modal-alert', + template: ` + + + + `, + encapsulation: ViewEncapsulation.None, +}) +/** + * API to an open alert window. + */ +export class AlertModal{ + /** + * Caption for the title. + */ + public alertTitle:string; + /** + * Describes if the alert contains Ok Button. + * The default Ok button will close the alert and emit the callback. + * Defaults to true. + */ + public okButton:boolean = true; + /** + * Caption for the OK button. + * Default: Ok + */ + public okButtonText:string= 'Ok'; + /** + * Describes if the alert contains cancel Button. + * The default Cancelbutton will close the alert. + * Defaults to true. + */ + public cancelButton:boolean = true; + /** + * Caption for the Cancel button. + * Default: Cancel + */ + public cancelButtonText:string = 'Cancel'; + /** + * if the alertMessage is true it will show the contentString inside alert body. + */ + public alertMessage:boolean = true; + /** + * Some message/content can be set in message which will be shown in alert body. + */ + public message:string; + /** + * if the value is true alert footer will be visible or else it will be hidden. + */ + public alertFooter:boolean= true; + /** + * shows alert header if the value is true. + */ + public alertHeader:boolean = true; + /** + * if the value is true alert will be visible or else it will be hidden. + */ + public isOpen:boolean=false; + /** + * Emitted when a ok button was clicked + * or when Ok method is called. + */ + @Output() public alertOutput:EventEmitter = new EventEmitter(); + constructor( public _elementRef: ElementRef){} + /** + * Opens a alert window creating backdrop. + */ + open(){ + this.isOpen= true; + } + /** + * ok method closes the modal and emits modalOutput. + */ + ok(){ + this.isOpen = false; + this.alertOutput.emit(true); + } + /** + * cancel method closes the moda. + */ + cancel(){ + this.isOpen = false; + } +} diff --git a/utils/modal/alertModal.module.ts b/utils/modal/alertModal.module.ts new file mode 100644 index 00000000..d39e168d --- /dev/null +++ b/utils/modal/alertModal.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {AlertModal} from './alert'; +import {ModalModule} from './modal.module'; + +@NgModule({ + imports: [ CommonModule, FormsModule, ModalModule ], + declarations: [ + AlertModal + ], + exports: [ + AlertModal + ] +}) +export class AlertModalModule { } diff --git a/utils/modal/loading.component.ts b/utils/modal/loading.component.ts new file mode 100644 index 00000000..55a5501e --- /dev/null +++ b/utils/modal/loading.component.ts @@ -0,0 +1,56 @@ +import {Component, ViewEncapsulation, ComponentRef, ElementRef, Input, EventEmitter, Output} from '@angular/core'; + +@Component({ + selector: 'modal-loading', + template: ` + +
    +
    + + +
    +
    +

    {{message}}

    +
    +
    +
    + +
    + +
    + + `, + encapsulation: ViewEncapsulation.None, +}) +/** + * API to an open alert window. + */ +export class ModalLoading{ + +@Input() public message:string ="Loading"; + + /** + * if the value is true alert will be visible or else it will be hidden. + */ + public isOpen:boolean=false; + /** + * Emitted when a ok button was clicked + * or when Ok method is called. + */ + @Output() public alertOutput:EventEmitter = new EventEmitter(); + constructor( public _elementRef: ElementRef){} + /** + * Opens a alert window creating backdrop. + */ + open(){ + this.isOpen= true; + } + + close(){ + this.isOpen = false; + } +} diff --git a/utils/modal/loadingModal.module.ts b/utils/modal/loadingModal.module.ts new file mode 100644 index 00000000..6edf5c4a --- /dev/null +++ b/utils/modal/loadingModal.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + + import {ModalLoading} from './loading.component'; +import {ModalModule} from './modal.module'; + +//helpers + +@NgModule({ + imports: [ CommonModule, FormsModule,ModalModule ], + declarations: [ + ModalLoading + ], + exports: [ + ModalLoading + ] +}) +export class LoadingModalModule { } diff --git a/utils/modal/modal.module.ts b/utils/modal/modal.module.ts new file mode 100644 index 00000000..fd48478c --- /dev/null +++ b/utils/modal/modal.module.ts @@ -0,0 +1,13 @@ +/* common components of modal components */ +import { NgModule } from '@angular/core'; +import {Open} from './open.component'; +@NgModule({ + imports: [ ], + declarations: [ + Open + ], + exports: [ + Open + ] +}) +export class ModalModule { } diff --git a/utils/modal/open.component.ts b/utils/modal/open.component.ts new file mode 100644 index 00000000..fb9f011e --- /dev/null +++ b/utils/modal/open.component.ts @@ -0,0 +1,57 @@ +import {Directive, Input, HostBinding} from '@angular/core'; + +// todo: add animate +// todo: add init and on change +@Directive({selector: '[open]'}) +export class Open { + @HostBinding('style.display') + public display:string; + @HostBinding('class.in') + @HostBinding('attr.aria-expanded') + public isExpanded:boolean = true; + + @Input() + public set open(value:boolean) { + this.isExpanded = value; + this.toggle(); + } + + public get open():boolean { + return this.isExpanded; + } + + constructor() { + } + init() { + this.isExpanded = false; + this.display = 'none'; + } + toggle() { + if (this.isExpanded) { + this.hide(); + } else { + this.show(); + } + } + + hide() { + this.isExpanded = false; + this.display = 'none'; + if (typeof document !== 'undefined') { + let backDrop = document.getElementsByClassName("modal-backdrop"); + if(backDrop.length>0){ + document.body.removeChild(backDrop[0]); + } + } + } + + show() { + if (typeof document !== 'undefined') { + // let backDrop = document.createElement('div'); + // backDrop.className="modal-backdrop fade in"; + // document.body.appendChild(backDrop); + } + this.isExpanded = true; + this.display = 'block'; + } +} diff --git a/utils/modal/selectModal.component.ts b/utils/modal/selectModal.component.ts new file mode 100644 index 00000000..78330b76 --- /dev/null +++ b/utils/modal/selectModal.component.ts @@ -0,0 +1,79 @@ +import {Component, ViewEncapsulation, ComponentRef, ElementRef, Input, EventEmitter, Output} from '@angular/core'; + +@Component({ + selector: 'modal-select', + template: ` +
    +
    + +
    + + `, + encapsulation: ViewEncapsulation.None, +}) +/** + * API to an open alert window. + */ +export class ModalSelect{ + +@Input() public message:string ="Loading"; +@Input() public options:string[] = []; + +public selected: string; + + /** + * if the value is true alert will be visible or else it will be hidden. + */ + public isOpen:boolean=false; + /** + * Emitted when a ok button was clicked + * or when Ok method is called. + */ + @Output() public alertOutput:EventEmitter = new EventEmitter(); + constructor( public _elementRef: ElementRef){} + /** + * Opens a alert window creating backdrop. + */ + open(){ + this.isOpen= true; + } + + close(){ + this.isOpen = false; + if(!this.selected) { + this.selected = this.options[0]; + } + this.alertOutput.emit(this.selected); + } + +} diff --git a/utils/modal/selectModal.module.ts b/utils/modal/selectModal.module.ts new file mode 100644 index 00000000..971a7dd7 --- /dev/null +++ b/utils/modal/selectModal.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + + import {ModalSelect} from './selectModal.component'; +import {ModalModule} from './modal.module'; + +//helpers + +@NgModule({ + imports: [ CommonModule, FormsModule,ModalModule ], + declarations: [ + ModalSelect + ], + exports: [ + ModalSelect + ] +}) +export class SelectModalModule { } diff --git a/utils/my-date-picker/directives/my-date-picker.focus.directive.ts b/utils/my-date-picker/directives/my-date-picker.focus.directive.ts new file mode 100644 index 00000000..5508ea6c --- /dev/null +++ b/utils/my-date-picker/directives/my-date-picker.focus.directive.ts @@ -0,0 +1,26 @@ +import { Directive, ElementRef, Renderer, AfterViewInit, Input } from "@angular/core"; + +@Directive({ + selector: "[mydpfocus]" +}) + +export class FocusDirective implements AfterViewInit { + @Input("mydpfocus") value: string; + + constructor(private el: ElementRef, private renderer: Renderer) {} + + // Focus to element: if value 0 = don't set focus, 1 = set only focus, 2 = set focus and set cursor position + ngAfterViewInit() { + if (this.value === "0") { + return; + } + + this.renderer.invokeElementMethod(this.el.nativeElement, "focus", []); + + // Set cursor position at the end of text if input element + if (this.value === "2") { + let len = this.el.nativeElement.value.length; + this.el.nativeElement.setSelectionRange(len, len); + } + } +} \ No newline at end of file diff --git a/utils/my-date-picker/directives/my-date-picker.input.auto.fill.directive.ts b/utils/my-date-picker/directives/my-date-picker.input.auto.fill.directive.ts new file mode 100644 index 00000000..ef1a1501 --- /dev/null +++ b/utils/my-date-picker/directives/my-date-picker.input.auto.fill.directive.ts @@ -0,0 +1,69 @@ +import { Directive, ElementRef, Renderer, Input, HostListener } from "@angular/core"; +import { IMyInputAutoFill } from "../interfaces/my-input-auto-fill.interface"; + +@Directive({ + selector: "[myinputautofill]" +}) + +export class InputAutoFillDirective { + @Input("myinputautofill") opts: IMyInputAutoFill; + + constructor(private el: ElementRef, private rndr: Renderer) {} + + @HostListener("keyup", ["$event"]) onKeyUp(evt: KeyboardEvent) { + if (!this.opts.enabled || evt.keyCode === 8 || evt.keyCode === 46) { + return; + } + + let val: string = this.getInputValue(); + let ews: boolean = this.endsWith(val, this.opts.separator); + let parts: Array = val.split(this.opts.separator); + let idx: number = parts.length - 1; + + if (val.indexOf(this.opts.separator + this.opts.separator) !== -1) { + return; + } + + if (!ews && (val.length === this.getPartLength(0) || val.length === this.getPartLength(0) + this.getPartLength(1) + this.opts.separator.length)) { + this.setInputValue(val + this.opts.separator); + } + else if (ews && parts[idx - 1].length < this.getPartLength(idx - 1) && this.isNumber(parts[idx - 1]) && (this.isDay(idx - 1) || this.isMonth(idx - 1))) { + this.setInputValue(this.insertPos(val, val.length - 2, "0")); + } + else if (parts[idx].length < this.getPartLength(idx) && this.isNumber(parts[idx]) && (Number(parts[idx]) > 3 && this.isDay(idx) || Number(parts[idx]) > 1 && this.isMonth(idx))) { + this.setInputValue(this.insertPos(val, val.length - 1, "0") + (idx < 2 ? this.opts.separator : "")); + } + } + + private endsWith(val: string, suffix: string): boolean { + return val.indexOf(suffix, val.length - suffix.length) !== -1; + } + + private insertPos(str: string, idx: number, val: string): string { + return str.substr(0, idx) + val + str.substr(idx); + } + + private getPartLength(idx: number): number { + return this.opts.formatParts[idx].length; + } + + private isNumber(val: string): boolean { + return val.match(/[1-9]/) !== null; + } + + private isDay(idx: number): boolean { + return this.opts.formatParts[idx].indexOf("d") !== -1; + } + + private isMonth(idx: number): boolean { + return this.opts.formatParts[idx].indexOf("m") !== -1 && this.opts.formatParts[idx].length === 2; + } + + private getInputValue(): string { + return this.el.nativeElement.value; + } + + private setInputValue(val: string): void { + this.rndr.setElementProperty(this.el.nativeElement, "value", val); + } +} \ No newline at end of file diff --git a/utils/my-date-picker/index.ts b/utils/my-date-picker/index.ts new file mode 100644 index 00000000..55613d2b --- /dev/null +++ b/utils/my-date-picker/index.ts @@ -0,0 +1,7 @@ +export * from "./services/my-date-picker.locale.service"; +export * from "./services/my-date-picker.util.service"; +export * from "./directives/my-date-picker.focus.directive"; +export * from "./directives/my-date-picker.input.auto.fill.directive"; +export * from "./my-date-picker.component"; +export * from "./my-date-picker.module"; +export * from "./interfaces/index"; \ No newline at end of file diff --git a/utils/my-date-picker/interfaces/index.ts b/utils/my-date-picker/interfaces/index.ts new file mode 100644 index 00000000..ab34b252 --- /dev/null +++ b/utils/my-date-picker/interfaces/index.ts @@ -0,0 +1,15 @@ +export * from "./my-date.interface"; +export * from "./my-date-range.interface"; +export * from "./my-day-labels.interface"; +export * from "./my-month-labels.interface"; +export * from "./my-month.interface"; +export * from "./my-calendar-day.interface"; +export * from "./my-week.interface"; +export * from "./my-options.interface"; +export * from "./my-locale.interface"; +export * from "./my-date-model.interface"; +export * from "./my-input-field-changed.interface"; +export * from "./my-input-focus-blur.interface"; +export * from "./my-weekday.interface"; +export * from "./my-calendar-view-changed.interface"; +export * from "./my-input-auto-fill.interface"; \ No newline at end of file diff --git a/utils/my-date-picker/interfaces/my-calendar-day.interface.ts b/utils/my-date-picker/interfaces/my-calendar-day.interface.ts new file mode 100644 index 00000000..d554243a --- /dev/null +++ b/utils/my-date-picker/interfaces/my-calendar-day.interface.ts @@ -0,0 +1,9 @@ +import { IMyDate } from "./my-date.interface"; + +export interface IMyCalendarDay { + dateObj: IMyDate; + cmo: number; + currDay: boolean; + dayNbr: number; + disabled: boolean; +} \ No newline at end of file diff --git a/utils/my-date-picker/interfaces/my-calendar-view-changed.interface.ts b/utils/my-date-picker/interfaces/my-calendar-view-changed.interface.ts new file mode 100644 index 00000000..9b9baa5e --- /dev/null +++ b/utils/my-date-picker/interfaces/my-calendar-view-changed.interface.ts @@ -0,0 +1,8 @@ +import { IMyWeekday } from "./my-weekday.interface"; + +export interface IMyCalendarViewChanged { + year: number; + month: number; + first: IMyWeekday; + last: IMyWeekday; +} diff --git a/utils/my-date-picker/interfaces/my-date-model.interface.ts b/utils/my-date-picker/interfaces/my-date-model.interface.ts new file mode 100644 index 00000000..35aa7535 --- /dev/null +++ b/utils/my-date-picker/interfaces/my-date-model.interface.ts @@ -0,0 +1,8 @@ +import { IMyDate } from "./my-date.interface"; + +export interface IMyDateModel { + date: IMyDate; + jsdate: Date; + formatted: string; + epoc: number; +} diff --git a/utils/my-date-picker/interfaces/my-date-range.interface.ts b/utils/my-date-picker/interfaces/my-date-range.interface.ts new file mode 100644 index 00000000..e24b319b --- /dev/null +++ b/utils/my-date-picker/interfaces/my-date-range.interface.ts @@ -0,0 +1,6 @@ +import { IMyDate } from "./my-date.interface"; + +export interface IMyDateRange { + begin: IMyDate; + end: IMyDate; +} diff --git a/utils/my-date-picker/interfaces/my-date.interface.ts b/utils/my-date-picker/interfaces/my-date.interface.ts new file mode 100644 index 00000000..99f00796 --- /dev/null +++ b/utils/my-date-picker/interfaces/my-date.interface.ts @@ -0,0 +1,5 @@ +export interface IMyDate { + year: number; + month: number; + day: number; +} diff --git a/utils/my-date-picker/interfaces/my-day-labels.interface.ts b/utils/my-date-picker/interfaces/my-day-labels.interface.ts new file mode 100644 index 00000000..f2fcfa24 --- /dev/null +++ b/utils/my-date-picker/interfaces/my-day-labels.interface.ts @@ -0,0 +1,3 @@ +export interface IMyDayLabels { + [day: string]: string; +} \ No newline at end of file diff --git a/utils/my-date-picker/interfaces/my-input-auto-fill.interface.ts b/utils/my-date-picker/interfaces/my-input-auto-fill.interface.ts new file mode 100644 index 00000000..695afa92 --- /dev/null +++ b/utils/my-date-picker/interfaces/my-input-auto-fill.interface.ts @@ -0,0 +1,5 @@ +export interface IMyInputAutoFill { + separator: string; + formatParts: Array; + enabled: boolean; +} diff --git a/utils/my-date-picker/interfaces/my-input-field-changed.interface.ts b/utils/my-date-picker/interfaces/my-input-field-changed.interface.ts new file mode 100644 index 00000000..c93530b6 --- /dev/null +++ b/utils/my-date-picker/interfaces/my-input-field-changed.interface.ts @@ -0,0 +1,5 @@ +export interface IMyInputFieldChanged { + value: string; + dateFormat: string; + valid: boolean; +} diff --git a/utils/my-date-picker/interfaces/my-input-focus-blur.interface.ts b/utils/my-date-picker/interfaces/my-input-focus-blur.interface.ts new file mode 100644 index 00000000..99678cbb --- /dev/null +++ b/utils/my-date-picker/interfaces/my-input-focus-blur.interface.ts @@ -0,0 +1,4 @@ +export interface IMyInputFocusBlur { + reason: number; + value: string; +} diff --git a/utils/my-date-picker/interfaces/my-locale.interface.ts b/utils/my-date-picker/interfaces/my-locale.interface.ts new file mode 100644 index 00000000..25d268ba --- /dev/null +++ b/utils/my-date-picker/interfaces/my-locale.interface.ts @@ -0,0 +1,5 @@ +import { IMyOptions } from "./my-options.interface"; + +export interface IMyLocales { + [lang: string]: IMyOptions; +} \ No newline at end of file diff --git a/utils/my-date-picker/interfaces/my-month-labels.interface.ts b/utils/my-date-picker/interfaces/my-month-labels.interface.ts new file mode 100644 index 00000000..0eede49b --- /dev/null +++ b/utils/my-date-picker/interfaces/my-month-labels.interface.ts @@ -0,0 +1,3 @@ +export interface IMyMonthLabels { + [month: number]: string; +} \ No newline at end of file diff --git a/utils/my-date-picker/interfaces/my-month.interface.ts b/utils/my-date-picker/interfaces/my-month.interface.ts new file mode 100644 index 00000000..846a23eb --- /dev/null +++ b/utils/my-date-picker/interfaces/my-month.interface.ts @@ -0,0 +1,5 @@ +export interface IMyMonth { + monthTxt: string; + monthNbr: number; + year: number; +} \ No newline at end of file diff --git a/utils/my-date-picker/interfaces/my-options.interface.ts b/utils/my-date-picker/interfaces/my-options.interface.ts new file mode 100644 index 00000000..89c26bea --- /dev/null +++ b/utils/my-date-picker/interfaces/my-options.interface.ts @@ -0,0 +1,48 @@ +import { IMyDayLabels } from "./my-day-labels.interface"; +import { IMyMonthLabels } from "./my-month-labels.interface"; +import { IMyDate } from "./my-date.interface"; +import { IMyDateRange } from "./my-date-range.interface"; + +export interface IMyOptions { + dayLabels?: IMyDayLabels; + monthLabels?: IMyMonthLabels; + dateFormat?: string; + showTodayBtn?: boolean; + todayBtnTxt?: string; + firstDayOfWeek?: string; + sunHighlight?: boolean; + markCurrentDay?: boolean; + disableUntil?: IMyDate; + disableSince?: IMyDate; + disableDays?: Array; + enableDays?: Array; + disableDateRange?: IMyDateRange; + disableWeekends?: boolean; + showWeekNumbers?: boolean; + height?: string; + width?: string; + selectionTxtFontSize?: string; + inline?: boolean; + showClearDateBtn?: boolean; + alignSelectorRight?: boolean; + openSelectorTopOfInput?: boolean; + indicateInvalidDate?: boolean; + editableDateField?: boolean; + editableMonthAndYear?: boolean; + disableHeaderButtons?: boolean; + minYear?: number; + maxYear?: number; + componentDisabled?: boolean; + inputValueRequired?: boolean; + showSelectorArrow?: boolean; + showInputField?: boolean; + openSelectorOnInputClick?: boolean; + inputAutoFill?: boolean; + ariaLabelInputField?: string; + ariaLabelClearDate?: string; + ariaLabelOpenCalendar?: string; + ariaLabelPrevMonth?: string; + ariaLabelNextMonth?: string; + ariaLabelPrevYear?: string; + ariaLabelNextYear?: string; +} diff --git a/utils/my-date-picker/interfaces/my-week.interface.ts b/utils/my-date-picker/interfaces/my-week.interface.ts new file mode 100644 index 00000000..be7bca16 --- /dev/null +++ b/utils/my-date-picker/interfaces/my-week.interface.ts @@ -0,0 +1,6 @@ +import { IMyCalendarDay } from "./my-calendar-day.interface"; + +export interface IMyWeek { + week: Array; + weekNbr: number; +} \ No newline at end of file diff --git a/utils/my-date-picker/interfaces/my-weekday.interface.ts b/utils/my-date-picker/interfaces/my-weekday.interface.ts new file mode 100644 index 00000000..da1df557 --- /dev/null +++ b/utils/my-date-picker/interfaces/my-weekday.interface.ts @@ -0,0 +1,4 @@ +export interface IMyWeekday { + number: number; + weekday: string; +} diff --git a/utils/my-date-picker/my-date-picker.component.css b/utils/my-date-picker/my-date-picker.component.css new file mode 100644 index 00000000..3c21416d --- /dev/null +++ b/utils/my-date-picker/my-date-picker.component.css @@ -0,0 +1,461 @@ +.mydp { + min-width: 30px; + border-radius: 2px; + line-height: 1.1; + display: inline-block; + position: relative; +} + +.mydp * { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + font-family: Arial, Helvetica, sans-serif; + padding: 0; + margin: 0; +} + +.mydp .selector { + margin-top: 2px; + margin-left: -1px; + position: absolute; + width: 252px; + padding: 0; + border: 1px solid #CCC; + border-radius: 2px; + z-index: 100; + animation: selectorfadein 0.1s; +} + +.mydp .selector:focus { + border: 1px solid #ADD8E6; + outline: none; +} + +@keyframes selectorfadein { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.mydp .selectorarrow { + background: #FAFAFA; + margin-top: 12px; + padding: 0; +} + +.mydp .selectorarrow:after, +.mydp .selectorarrow:before { + bottom: 100%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; +} + +.mydp .selectorarrow:after { + border-color: rgba(250, 250, 250, 0); + border-bottom-color: #FAFAFA; + border-width: 10px; + margin-left: -10px; +} + +.mydp .selectorarrow:before { + border-color: rgba(204, 204, 204, 0); + border-bottom-color: #CCC; + border-width: 11px; + margin-left: -11px; +} + +.mydp .selectorarrow:focus:before { + border-bottom-color: #ADD8E6; +} + +.mydp .selectorarrowleft:after, +.mydp .selectorarrowleft:before { + left: 24px; +} + +.mydp .selectorarrowright:after, +.mydp .selectorarrowright:before { + left: 224px; +} + +.mydp .alignselectorright { + right: -1px; +} + +.mydp .selectiongroup { + position: relative; + display: table; + border: none; + border-spacing: 0; + background-color: #FFF; +} + +.mydp .selection { + outline: none; + background-color: #FFF; + display: table-cell; + position: absolute; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + text-align: center; +} + +.mydp .invaliddate, +.mydp .invalidmonth, +.mydp .invalidyear { + background-color: #F1DEDE; +} + +.mydp ::-ms-clear { + display: none; +} + +.mydp .selbtngroup { + position: relative; + vertical-align: middle; + white-space: nowrap; + width: 1%; + display: table-cell; + font-size: 0; +} + +.mydp .btnpicker, +.mydp .btnclear { + height: 100%; + width: 30px; + border: none; + padding: 0; + outline: 0; + font: inherit; + -moz-user-select: none; +} + +.mydp .btnleftborder { + border-left: 1px solid #CCC; +} + +.mydp .btnpickerenabled, +.mydp .btnclearenabled, +.mydp .headertodaybtnenabled, +.mydp .headerbtnenabled { + cursor: pointer; +} + +.mydp .btnpickerdisabled, +.mydp .btncleardisabled, +.mydp .headertodaybtndisabled, +.mydp .headerbtndisabled { + cursor: not-allowed; +} + +.mydp .headerbtndisabled { + opacity: 0.4; +} + +.mydp .btnpicker, +.mydp .btnclear, +.mydp .headertodaybtn { + background: #FFF; +} + +.mydp .header { + width: 100%; + height: 30px; + background-color: #FAFAFA; +} + +.mydp .header td { + vertical-align: middle; + border: none; + line-height: 0; +} + +.mydp .header td:nth-child(1) { + padding-left: 4px; +} + +.mydp .header td:nth-child(2) { + text-align: center; +} + +.mydp .header td:nth-child(3) { + padding-right: 4px; +} + +.mydp .caltable { + table-layout: fixed; + width: 100%; + background-color: #FFF; + font-size: 14px; +} + +.mydp .caltable, +.mydp .weekdaytitle, +.mydp .daycell { + border-collapse: collapse; + color: #003366; + line-height: 1.1; +} + +.mydp .weekdaytitle, +.mydp .daycell { + padding: 5px; + text-align: center; +} + +.mydp .weekdaytitle { + background-color: #DDD; + font-size: 12px; + font-weight: bold; + vertical-align: middle; + max-width: 36px; + overflow: hidden; + white-space: nowrap; +} + +.mydp .weekdaytitleweeknbr { + width: 20px; + border-right: 1px solid #BBB; +} + +.mydp .daycell { + cursor: pointer; + height: 30px; +} + +.mydp .daycell div { + background-color: inherit; + vertical-align: middle; +} + +.mydp .daycell div span { + vertical-align: middle; +} + +.mydp .daycellweeknbr { + font-size: 10px; + border-right: 1px solid #CCC; + cursor: default; + color: #000; +} + +.mydp .inlinedp { + position: relative; + margin-top: -1px; +} + +.mydp .prevmonth { + color: #CCC; +} + +.mydp .nextmonth { + color: #CCC; +} + +.mydp .disabled { + cursor: default !important; + color: #CCC !important; + background: #FBEFEF !important; +} + +.mydp .sunday { + color: #C30000; +} + +.mydp .sundayDim { + opacity: 0.5; +} + +.mydp .currmonth { + background-color: #F6F6F6; + font-weight: bold; +} + +.mydp .currday { + text-decoration: underline; +} + +.mydp .selectedday div { + border: 1px solid #004198; + background-color: #8EBFFF !important; + border-radius: 2px; +} + +.mydp .headerbtncell { + background-color: #FAFAFA; + display: table-cell; + vertical-align: middle; +} + +.mydp .headerbtn, +.mydp .headerlabelbtn { + background: #FAFAFA; + border: none; + height: 22px; +} + +.mydp .headerbtn { + width: 16px; +} + +.mydp .headerlabelbtn { + font-size: 14px; +} + +.mydp, +.mydp .headertodaybtn, +.mydp .monthinput, +.mydp .yearinput { + border: 1px solid #CCC; +} + +.mydp .btnpicker, +.mydp .btnclear, +.mydp .headerbtn, +.mydp .headermonthtxt, +.mydp .headeryeartxt, +.mydp .headertodaybtn, +.mydp .selection { + color: #000; +} + +.mydp .headertodaybtn { + padding: 0 4px; + border-radius: 2px; + font-size: 11px; + height: 22px; + min-width: 60px; + max-width: 70px; + overflow: hidden; + white-space: nowrap; +} + +.mydp button::-moz-focus-inner { + border: 0; +} + +.mydp .headermonthtxt, +.mydp .headeryeartxt { + text-align: center; + display: table-cell; + vertical-align: middle; + font-size: 14px; + height: 26px; + width: 40px; + max-width: 40px; + overflow: hidden; + white-space: nowrap; +} + +.mydp .btnclear:focus, +.mydp .btnpicker:focus, +.mydp .headertodaybtn:focus { + background: #ADD8E6; +} + +.mydp .headerbtn:focus, +.mydp .monthlabel:focus, +.mydp .yearlabel:focus { + color: #ADD8E6; + outline: none; +} + +.mydp .daycell:focus { + outline: 1px solid #CCC; +} + +.mydp .icon-mydpcalendar, +.mydp .icon-mydpremove { + font-size: 16px; +} + +.mydp .icon-mydpleft, +.mydp .icon-mydpright { + color: #222; + font-size: 20px; +} + +.mydp table { + display: table; + border-spacing: 0; +} + +.mydp table td { + padding: 0; +} + +.mydp table, +.mydp th, +.mydp td { + border: none; +} + +.mydp .btnpickerenabled:hover, +.mydp .btnclearenabled:hover, +.mydp .headertodaybtnenabled:hover, +.mydp .tablesingleday:hover { + background-color: #8BDAF4; +} + +.mydp .monthlabel, +.mydp .yearlabel { + cursor: pointer; +} + +.mydp .yearinput, +.mydp .monthinput { + width: 40px; + height: 22px; + text-align: center; + font-weight: bold; + outline: none; + border-radius: 2px; +} + +.mydp .headerbtnenabled:hover, +.mydp .monthlabel:hover, +.mydp .yearlabel:hover { + color: #8BDAF4; +} + +@font-face { + font-family: 'mydatepicker'; + src: url('data:application/octet-stream;base64,AAEAAAAPAIAAAwBwR1NVQiCMJXkAAAD8AAAAVE9TLzI+IEhBAAABUAAAAFZjbWFwEIvU5AAAAagAAAGiY3Z0IAbV/wQAAApQAAAAIGZwZ22KkZBZAAAKcAAAC3BnYXNwAAAAEAAACkgAAAAIZ2x5ZsNblX4AAANMAAADBGhlYWQM+nt/AAAGUAAAADZoaGVhBz0DVgAABogAAAAkaG10eA1jAAAAAAasAAAAFGxvY2EBWgHMAAAGwAAAAAxtYXhwAXUMOgAABswAAAAgbmFtZZKUFgMAAAbsAAAC/XBvc3TOA7dOAAAJ7AAAAFpwcmVw5UErvAAAFeAAAACGAAEAAAAKADAAPgACbGF0bgAOREZMVAAaAAQAAAAAAAAAAQAAAAQAAAAAAAAAAQAAAAFsaWdhAAgAAAABAAAAAQAEAAQAAAABAAgAAQAGAAAAAQAAAAECrQGQAAUAAAJ6ArwAAACMAnoCvAAAAeAAMQECAAACAAUDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBmRWQAQOgA6AUDUv9qAFoDUgCWAAAAAQAAAAAAAAAAAAUAAAADAAAALAAAAAQAAAFiAAEAAAAAAFwAAwABAAAALAADAAoAAAFiAAQAMAAAAAYABAABAALoAugF//8AAOgA6AX//wAAAAAAAQAGAAoAAAABAAIAAwAEAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAABAAAAAAAAAAAQAAOgAAADoAAAAAAEAAOgBAADoAQAAAAIAAOgCAADoAgAAAAMAAOgFAADoBQAAAAQAAAABAAAAAAFBAn0ADgAKtwAAAGYUAQUVKwEUDwEGIiY1ETQ+AR8BFgFBCvoLHBYWHAv6CgFeDgv6CxYOAfQPFAIM+goAAAEAAAAAAWcCfAANABdAFAABAAEBRwABAAFvAAAAZhcTAgUWKwERFAYiLwEmND8BNjIWAWUUIAn6Cgr6CxwYAlj+DA4WC/oLHAv6CxYAAAAADwAA/2oDoQNSAAMABwALAA8AEwAXABsAHwAjADMANwA7AD8ATwBzAJhAlUElAh0SSS0kAxMdAkchHwIdEwkdVBsBExkXDQMJCBMJXxgWDAMIFREHAwUECAVeFBAGAwQPCwMDAQAEAV4aARISHlggAR4eDEgOCgIDAAAcWAAcHA0cSXJwbWpnZmNgXVtWU01MRUQ/Pj08Ozo5ODc2NTQxLyknIyIhIB8eHRwbGhkYFxYVFBMSEREREREREREQIgUdKxczNSMXMzUjJzM1IxczNSMnMzUjATM1IyczNSMBMzUjJzM1IwM1NCYnIyIGBxUUFjczMjYBMzUjJzM1IxczNSM3NTQmJyMiBhcVFBY3MzI2NxEUBiMhIiY1ETQ2OwE1NDY7ATIWHQEzNTQ2OwEyFgcVMzIWR6GhxbKyxaGhxbKyxaGhAZuzs9aysgGsoaHWs7PEDAYkBwoBDAYkBwoBm6Gh1rOz1qGhEgoIIwcMAQoIIwgK1ywc/O4dKiodSDQlJCU01jYkIyU2AUcdKk+hoaEksrKyJKH9xKH6of3EoSSyATChBwoBDAahBwwBCv4msiShoaFroQcKAQwGoQcMAQos/TUdKiodAssdKjYlNDQlNjYlNDQlNioAAAABAAD/7wLUAoYAJAAeQBsiGRAHBAACAUcDAQIAAm8BAQAAZhQcFBQEBRgrJRQPAQYiLwEHBiIvASY0PwEnJjQ/ATYyHwE3NjIfARYUDwEXFgLUD0wQLBCkpBAsEEwQEKSkEBBMECwQpKQQLBBMDw+kpA9wFhBMDw+lpQ8PTBAsEKSkECwQTBAQpKQQEEwPLg+kpA8AAQAAAAEAAGAI8Y9fDzz1AAsD6AAAAADU+ZvvAAAAANT5m+8AAP9qA+gDUgAAAAgAAgAAAAAAAAABAAADUv9qAAAD6AAA//4D6AABAAAAAAAAAAAAAAAAAAAABQPoAAABZQAAAWUAAAOgAAADEQAAAAAAAAAiAEoBOAGCAAEAAAAFAHQADwAAAAAAAgBEAFQAcwAAAKkLcAAAAAAAAAASAN4AAQAAAAAAAAA1AAAAAQAAAAAAAQAMADUAAQAAAAAAAgAHAEEAAQAAAAAAAwAMAEgAAQAAAAAABAAMAFQAAQAAAAAABQALAGAAAQAAAAAABgAMAGsAAQAAAAAACgArAHcAAQAAAAAACwATAKIAAwABBAkAAABqALUAAwABBAkAAQAYAR8AAwABBAkAAgAOATcAAwABBAkAAwAYAUUAAwABBAkABAAYAV0AAwABBAkABQAWAXUAAwABBAkABgAYAYsAAwABBAkACgBWAaMAAwABBAkACwAmAflDb3B5cmlnaHQgKEMpIDIwMTcgYnkgb3JpZ2luYWwgYXV0aG9ycyBAIGZvbnRlbGxvLmNvbW15ZGF0ZXBpY2tlclJlZ3VsYXJteWRhdGVwaWNrZXJteWRhdGVwaWNrZXJWZXJzaW9uIDEuMG15ZGF0ZXBpY2tlckdlbmVyYXRlZCBieSBzdmcydHRmIGZyb20gRm9udGVsbG8gcHJvamVjdC5odHRwOi8vZm9udGVsbG8uY29tAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMQA3ACAAYgB5ACAAbwByAGkAZwBpAG4AYQBsACAAYQB1AHQAaABvAHIAcwAgAEAAIABmAG8AbgB0AGUAbABsAG8ALgBjAG8AbQBtAHkAZABhAHQAZQBwAGkAYwBrAGUAcgBSAGUAZwB1AGwAYQByAG0AeQBkAGEAdABlAHAAaQBjAGsAZQByAG0AeQBkAGEAdABlAHAAaQBjAGsAZQByAFYAZQByAHMAaQBvAG4AIAAxAC4AMABtAHkAZABhAHQAZQBwAGkAYwBrAGUAcgBHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAGgAdAB0AHAAOgAvAC8AZgBvAG4AdABlAGwAbABvAC4AYwBvAG0AAAAAAgAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAQIBAwEEAQUBBgAJbXlkcHJpZ2h0CG15ZHBsZWZ0DG15ZHBjYWxlbmRhcgpteWRwcmVtb3ZlAAAAAAABAAH//wAPAAAAAAAAAAAAAAAAAAAAAAAYABgAGAAYA1L/agNS/2qwACwgsABVWEVZICBLuAAOUUuwBlNaWLA0G7AoWWBmIIpVWLACJWG5CAAIAGNjI2IbISGwAFmwAEMjRLIAAQBDYEItsAEssCBgZi2wAiwgZCCwwFCwBCZasigBCkNFY0VSW1ghIyEbilggsFBQWCGwQFkbILA4UFghsDhZWSCxAQpDRWNFYWSwKFBYIbEBCkNFY0UgsDBQWCGwMFkbILDAUFggZiCKimEgsApQWGAbILAgUFghsApgGyCwNlBYIbA2YBtgWVlZG7ABK1lZI7AAUFhlWVktsAMsIEUgsAQlYWQgsAVDUFiwBSNCsAYjQhshIVmwAWAtsAQsIyEjISBksQViQiCwBiNCsQEKQ0VjsQEKQ7ABYEVjsAMqISCwBkMgiiCKsAErsTAFJbAEJlFYYFAbYVJZWCNZISCwQFNYsAErGyGwQFkjsABQWGVZLbAFLLAHQyuyAAIAQ2BCLbAGLLAHI0IjILAAI0JhsAJiZrABY7ABYLAFKi2wBywgIEUgsAtDY7gEAGIgsABQWLBAYFlmsAFjYESwAWAtsAgssgcLAENFQiohsgABAENgQi2wCSywAEMjRLIAAQBDYEItsAosICBFILABKyOwAEOwBCVgIEWKI2EgZCCwIFBYIbAAG7AwUFiwIBuwQFlZI7AAUFhlWbADJSNhRESwAWAtsAssICBFILABKyOwAEOwBCVgIEWKI2EgZLAkUFiwABuwQFkjsABQWGVZsAMlI2FERLABYC2wDCwgsAAjQrILCgNFWCEbIyFZKiEtsA0ssQICRbBkYUQtsA4ssAFgICCwDENKsABQWCCwDCNCWbANQ0qwAFJYILANI0JZLbAPLCCwEGJmsAFjILgEAGOKI2GwDkNgIIpgILAOI0IjLbAQLEtUWLEEZERZJLANZSN4LbARLEtRWEtTWLEEZERZGyFZJLATZSN4LbASLLEAD0NVWLEPD0OwAWFCsA8rWbAAQ7ACJUKxDAIlQrENAiVCsAEWIyCwAyVQWLEBAENgsAQlQoqKIIojYbAOKiEjsAFhIIojYbAOKiEbsQEAQ2CwAiVCsAIlYbAOKiFZsAxDR7ANQ0dgsAJiILAAUFiwQGBZZrABYyCwC0NjuAQAYiCwAFBYsEBgWWawAWNgsQAAEyNEsAFDsAA+sgEBAUNgQi2wEywAsQACRVRYsA8jQiBFsAsjQrAKI7ABYEIgYLABYbUQEAEADgBCQopgsRIGK7ByKxsiWS2wFCyxABMrLbAVLLEBEystsBYssQITKy2wFyyxAxMrLbAYLLEEEystsBkssQUTKy2wGiyxBhMrLbAbLLEHEystsBwssQgTKy2wHSyxCRMrLbAeLACwDSuxAAJFVFiwDyNCIEWwCyNCsAojsAFgQiBgsAFhtRAQAQAOAEJCimCxEgYrsHIrGyJZLbAfLLEAHistsCAssQEeKy2wISyxAh4rLbAiLLEDHistsCMssQQeKy2wJCyxBR4rLbAlLLEGHistsCYssQceKy2wJyyxCB4rLbAoLLEJHistsCksIDywAWAtsCosIGCwEGAgQyOwAWBDsAIlYbABYLApKiEtsCsssCorsCoqLbAsLCAgRyAgsAtDY7gEAGIgsABQWLBAYFlmsAFjYCNhOCMgilVYIEcgILALQ2O4BABiILAAUFiwQGBZZrABY2AjYTgbIVktsC0sALEAAkVUWLABFrAsKrABFTAbIlktsC4sALANK7EAAkVUWLABFrAsKrABFTAbIlktsC8sIDWwAWAtsDAsALABRWO4BABiILAAUFiwQGBZZrABY7ABK7ALQ2O4BABiILAAUFiwQGBZZrABY7ABK7AAFrQAAAAAAEQ+IzixLwEVKi2wMSwgPCBHILALQ2O4BABiILAAUFiwQGBZZrABY2CwAENhOC2wMiwuFzwtsDMsIDwgRyCwC0NjuAQAYiCwAFBYsEBgWWawAWNgsABDYbABQ2M4LbA0LLECABYlIC4gR7AAI0KwAiVJiopHI0cjYSBYYhshWbABI0KyMwEBFRQqLbA1LLAAFrAEJbAEJUcjRyNhsAlDK2WKLiMgIDyKOC2wNiywABawBCWwBCUgLkcjRyNhILAEI0KwCUMrILBgUFggsEBRWLMCIAMgG7MCJgMaWUJCIyCwCEMgiiNHI0cjYSNGYLAEQ7ACYiCwAFBYsEBgWWawAWNgILABKyCKimEgsAJDYGQjsANDYWRQWLACQ2EbsANDYFmwAyWwAmIgsABQWLBAYFlmsAFjYSMgILAEJiNGYTgbI7AIQ0awAiWwCENHI0cjYWAgsARDsAJiILAAUFiwQGBZZrABY2AjILABKyOwBENgsAErsAUlYbAFJbACYiCwAFBYsEBgWWawAWOwBCZhILAEJWBkI7ADJWBkUFghGyMhWSMgILAEJiNGYThZLbA3LLAAFiAgILAFJiAuRyNHI2EjPDgtsDgssAAWILAII0IgICBGI0ewASsjYTgtsDkssAAWsAMlsAIlRyNHI2GwAFRYLiA8IyEbsAIlsAIlRyNHI2EgsAUlsAQlRyNHI2GwBiWwBSVJsAIlYbkIAAgAY2MjIFhiGyFZY7gEAGIgsABQWLBAYFlmsAFjYCMuIyAgPIo4IyFZLbA6LLAAFiCwCEMgLkcjRyNhIGCwIGBmsAJiILAAUFiwQGBZZrABYyMgIDyKOC2wOywjIC5GsAIlRlJYIDxZLrErARQrLbA8LCMgLkawAiVGUFggPFkusSsBFCstsD0sIyAuRrACJUZSWCA8WSMgLkawAiVGUFggPFkusSsBFCstsD4ssDUrIyAuRrACJUZSWCA8WS6xKwEUKy2wPyywNiuKICA8sAQjQoo4IyAuRrACJUZSWCA8WS6xKwEUK7AEQy6wKystsEAssAAWsAQlsAQmIC5HI0cjYbAJQysjIDwgLiM4sSsBFCstsEEssQgEJUKwABawBCWwBCUgLkcjRyNhILAEI0KwCUMrILBgUFggsEBRWLMCIAMgG7MCJgMaWUJCIyBHsARDsAJiILAAUFiwQGBZZrABY2AgsAErIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbACYiCwAFBYsEBgWWawAWNhsAIlRmE4IyA8IzgbISAgRiNHsAErI2E4IVmxKwEUKy2wQiywNSsusSsBFCstsEMssDYrISMgIDywBCNCIzixKwEUK7AEQy6wKystsEQssAAVIEewACNCsgABARUUEy6wMSotsEUssAAVIEewACNCsgABARUUEy6wMSotsEYssQABFBOwMiotsEcssDQqLbBILLAAFkUjIC4gRoojYTixKwEUKy2wSSywCCNCsEgrLbBKLLIAAEErLbBLLLIAAUErLbBMLLIBAEErLbBNLLIBAUErLbBOLLIAAEIrLbBPLLIAAUIrLbBQLLIBAEIrLbBRLLIBAUIrLbBSLLIAAD4rLbBTLLIAAT4rLbBULLIBAD4rLbBVLLIBAT4rLbBWLLIAAEArLbBXLLIAAUArLbBYLLIBAEArLbBZLLIBAUArLbBaLLIAAEMrLbBbLLIAAUMrLbBcLLIBAEMrLbBdLLIBAUMrLbBeLLIAAD8rLbBfLLIAAT8rLbBgLLIBAD8rLbBhLLIBAT8rLbBiLLA3Ky6xKwEUKy2wYyywNyuwOystsGQssDcrsDwrLbBlLLAAFrA3K7A9Ky2wZiywOCsusSsBFCstsGcssDgrsDsrLbBoLLA4K7A8Ky2waSywOCuwPSstsGossDkrLrErARQrLbBrLLA5K7A7Ky2wbCywOSuwPCstsG0ssDkrsD0rLbBuLLA6Ky6xKwEUKy2wbyywOiuwOystsHAssDorsDwrLbBxLLA6K7A9Ky2wciyzCQQCA0VYIRsjIVlCK7AIZbADJFB4sAEVMC0AS7gAyFJYsQEBjlmwAbkIAAgAY3CxAAVCsgABACqxAAVCswoCAQgqsQAFQrMOAAEIKrEABkK6AsAAAQAJKrEAB0K6AEAAAQAJKrEDAESxJAGIUViwQIhYsQNkRLEmAYhRWLoIgAABBECIY1RYsQMARFlZWVmzDAIBDCq4Af+FsASNsQIARAAA') format('truetype'); + font-weight: normal; + font-style: normal; +} + +.mydp .mydpicon { + font-family: 'mydatepicker'; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.mydp .icon-mydpright:before { + content: "\e800"; +} + +.mydp .icon-mydpleft:before { + content: "\e801"; +} + +.mydp .icon-mydpcalendar:before { + content: "\e802"; +} + +.mydp .icon-mydpremove:before { + content: "\e805"; +} diff --git a/utils/my-date-picker/my-date-picker.component.html b/utils/my-date-picker/my-date-picker.component.html new file mode 100644 index 00000000..9b7280e0 --- /dev/null +++ b/utils/my-date-picker/my-date-picker.component.html @@ -0,0 +1,61 @@ +
    +
    + +
    + + +
    +
    +
    + + + + + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    +
    + + + + + + + + +
    #{{d}}
    {{w.weekNbr}} +
    + {{d.dateObj.day}} +
    +
    +
    +
    diff --git a/utils/my-date-picker/my-date-picker.component.spec.ts b/utils/my-date-picker/my-date-picker.component.spec.ts new file mode 100644 index 00000000..83801d58 --- /dev/null +++ b/utils/my-date-picker/my-date-picker.component.spec.ts @@ -0,0 +1,2209 @@ +// // +// +// import {ComponentFixture, TestBed} from '@angular/core/testing'; +// import {By} from '@angular/platform-browser'; +// import {DebugElement} from '@angular/core'; +// import {MyDatePicker} from './my-date-picker.component'; +// import {FocusDirective} from './directives/my-date-picker.focus.directive'; +// import {InputAutoFillDirective} from './directives/my-date-picker.input.auto.fill.directive'; +// +// let comp: MyDatePicker; +// let fixture: ComponentFixture; +// let de: DebugElement; +// let el: HTMLElement; +// +// let PREVMONTH: string = '.header tr td:first-child div .headerbtncell:first-child .headerbtn'; +// let NEXTMONTH: string = '.header tr td:first-child div .headerbtncell:last-child .headerbtn'; +// let PREVYEAR: string = '.header tr td:last-child div .headerbtncell:first-child .headerbtn'; +// let NEXTYEAR: string = '.header tr td:last-child div .headerbtncell:last-child .headerbtn'; +// +// function getDateString(date:any):string { +// return date.getFullYear() + '-' + ((date.getMonth() + 1) < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)) + '-' + (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()); +// } +// +// function getElement(id:string):DebugElement { +// return de.query(By.css(id)); +// } +// +// function getElements(id:string):Array { +// return de.queryAll(By.css(id)); +// } +// +// describe('MyDatePicker', () => { +// beforeEach(() => { +// TestBed.configureTestingModule({ +// declarations: [MyDatePicker, FocusDirective, InputAutoFillDirective], +// }); +// +// fixture = TestBed.createComponent(MyDatePicker); +// +// comp = fixture.componentInstance; +// +// de = fixture.debugElement.query(By.css('.mydp')); +// el = de.nativeElement; +// }); +// +// it('set valid date', () => { +// comp.selectionDayTxt = '2016-08-22'; +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain('2016-08-22'); +// }); +// +// it('open/close selector', () => { +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// let selector = getElement('.selector'); +// expect(selector).toBe(null); +// +// btnpicker.nativeElement.click(); +// fixture.detectChanges(); +// selector = getElement('.selector'); +// expect(selector).not.toBe(null); +// +// btnpicker.nativeElement.click(); +// fixture.detectChanges(); +// selector = getElement('.selector'); +// expect(selector).toBe(null); +// }); +// +// it('select current day from the selector and clear', () => { +// let date = new Date(); +// comp.selectedMonth = {monthTxt: '', monthNbr: date.getMonth() + 1, year: date.getFullYear()}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// +// currday.nativeElement.click(); +// +// let dateStr = getDateString(date); +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain(dateStr); +// +// fixture.detectChanges(); +// let btnclear = getElement('.btnclear'); +// btnclear.nativeElement.click(); +// expect(selection.nativeElement.value).toContain(''); +// }); +// +// it('select/unselect current day from the selector', () => { +// let date = new Date(); +// comp.selectedMonth = {monthTxt: '', monthNbr: date.getMonth() + 1, year: date.getFullYear()}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// +// currday.nativeElement.click(); +// +// let dateStr = getDateString(date); +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain(dateStr); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// +// fixture.detectChanges(); +// let selectedday = getElement('.selectedday'); +// expect(selectedday).not.toBe(null); +// +// fixture.detectChanges(); +// currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// currday.nativeElement.click(); +// +// fixture.detectChanges(); +// selectedday = getElement('.selectedday'); +// expect(selectedday).toBe(null); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe(''); +// }); +// +// it('select today button', () => { +// let date = new Date(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let today = getElement('.headertodaybtn'); +// expect(today).not.toBe(null); +// +// today.nativeElement.click(); +// +// let dateStr = getDateString(date); +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain(dateStr); +// +// fixture.detectChanges(); +// let btnclear = getElement('.btnclear'); +// btnclear.nativeElement.click(); +// expect(selection.nativeElement.value).toContain(''); +// }); +// +// it('select previous month', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let prevmonth = getElement('.header tr td:first-child .headerbtn:first-child'); +// expect(prevmonth).not.toBe(null); +// +// prevmonth.nativeElement.click(); +// +// expect(comp.visibleMonth.monthTxt).toBe('Apr'); +// expect(comp.visibleMonth.monthNbr).toBe(4); +// expect(comp.visibleMonth.year).toBe(2016); +// }); +// +// it('select next month', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// +// nextmonth.nativeElement.click(); +// +// expect(comp.visibleMonth.monthTxt).toBe('Jun'); +// expect(comp.visibleMonth.monthNbr).toBe(6); +// expect(comp.visibleMonth.year).toBe(2016); +// }); +// +// it('select previous month january change year', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let prevmonth = getElement(PREVMONTH); +// expect(prevmonth).not.toBe(null); +// +// prevmonth.nativeElement.click(); +// +// expect(comp.visibleMonth.year).toBe(2015); +// }); +// +// it('select next month december change year', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 12, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// +// nextmonth.nativeElement.click(); +// +// expect(comp.visibleMonth.year).toBe(2017); +// }); +// +// it('select previous month from selector', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let prevmonth = getElement(PREVMONTH); +// expect(prevmonth).not.toBe(null); +// +// prevmonth.nativeElement.click(); +// expect(comp.visibleMonth.monthNbr).toBe(4); +// expect(comp.visibleMonth.monthTxt).toBe('Apr'); +// +// prevmonth.nativeElement.click(); +// expect(comp.visibleMonth.monthNbr).toBe(3); +// expect(comp.visibleMonth.monthTxt).toBe('Mar'); +// }); +// +// it('select next month from selector', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// +// nextmonth.nativeElement.click(); +// expect(comp.visibleMonth.monthNbr).toBe(6); +// expect(comp.visibleMonth.monthTxt).toBe('Jun'); +// +// nextmonth.nativeElement.click(); +// expect(comp.visibleMonth.monthNbr).toBe(7); +// expect(comp.visibleMonth.monthTxt).toBe('Jul'); +// }); +// +// it('select previous year', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let prevyear = getElement(PREVYEAR); +// expect(prevyear).not.toBe(null); +// +// prevyear.nativeElement.click(); +// fixture.detectChanges(); +// let yearLabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearLabel).not.toBe(null); +// expect(yearLabel.nativeElement.textContent).toBe('2015'); +// }); +// +// it('select next year', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let nextyear = getElement(NEXTYEAR); +// expect(nextyear).not.toBe(null); +// +// nextyear.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearLabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearLabel).not.toBe(null); +// expect(yearLabel.nativeElement.textContent).toBe('2017'); +// }); +// +// it('test calendar year 2016 month one by one - next month button', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// +// comp.options = {firstDayOfWeek: 'mo'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let monthlabel = getElement('.monthlabel'); +// expect(monthlabel).not.toBe(null); +// expect(monthlabel.nativeElement.textContent.trim()).toBe('Jan'); +// +// fixture.detectChanges(); +// let yearlabel = getElement('.yearlabel'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent.trim()).toBe('2016'); +// +// comp.generateCalendar(1, 2016, true); +// +// let beginDate: Array = ['28', '1', '29', '28', '25', '30', '27', '1', '29', '26', '31', '28']; +// let endDate: Array = ['7', '13', '10', '8', '5', '10', '7', '11', '9', '6', '11', '8']; +// +// let i: number = 0; +// do { +// fixture.detectChanges(); +// let currmonth = getElements('.caltable tbody tr td'); +// expect(currmonth).not.toBe(null); +// expect(currmonth.length).toBe(42); +// +// expect(currmonth[0]).not.toBe(null); +// expect(currmonth[0].nativeElement.textContent.trim()).toBe(beginDate[i]); +// +// expect(currmonth[41]).not.toBe(null); +// expect(currmonth[41].nativeElement.textContent.trim()).toBe(endDate[i]); +// +// comp.nextMonth(); +// +// i++; +// } while (i < 12) +// }); +// +// it('test calendar year 2016 month one by one - previous month button', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 12, year: 2016}; +// +// comp.options = {firstDayOfWeek: 'mo'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let monthlabel = getElement('.monthlabel'); +// expect(monthlabel).not.toBe(null); +// expect(monthlabel.nativeElement.textContent.trim()).toBe('Dec'); +// +// fixture.detectChanges(); +// let yearlabel = getElement('.yearlabel'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent.trim()).toBe('2016'); +// +// comp.generateCalendar(12, 2016, true); +// +// let beginDate: Array = ['28', '1', '29', '28', '25', '30', '27', '1', '29', '26', '31', '28']; +// let endDate: Array = ['7', '13', '10', '8', '5', '10', '7', '11', '9', '6', '11', '8']; +// +// let i: number = 11; +// do { +// fixture.detectChanges(); +// let currmonth = getElements('.caltable tbody tr td'); +// expect(currmonth).not.toBe(null); +// expect(currmonth.length).toBe(42); +// +// expect(currmonth[0]).not.toBe(null); +// expect(currmonth[0].nativeElement.textContent.trim()).toBe(beginDate[i]); +// +// expect(currmonth[41]).not.toBe(null); +// expect(currmonth[41].nativeElement.textContent.trim()).toBe(endDate[i]); +// +// comp.prevMonth(); +// +// i--; +// } while (i >= 0) +// }); +// +// // options +// it('options - dayLabels', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// comp.options = {dayLabels: {su: '1', mo: '2', tu: '3', we: '4', th: '5', fr: '6', sa: '7'}, firstDayOfWeek: 'su'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let ths = getElements('.caltable thead tr th'); +// expect(ths.length).toBe(7); +// for(let i in ths) { +// let el = ths[i]; +// expect(parseInt(el.nativeElement.textContent)).toBe(parseInt(i) + 1); +// } +// }); +// +// it('options - monthLabels', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// comp.options = {monthLabels: { 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10: '10', 11: '11', 12: '12' }}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// +// for(let i = 1; i <= 12; i++) { +// fixture.detectChanges(); +// let monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(parseInt(monthLabel.nativeElement.textContent)).toBe(i); +// nextmonth.nativeElement.click(); +// } +// }); +// +// it('options - date format', () => { +// comp.options = {dateFormat: 'dd.mm.yyyy', indicateInvalidDate: true}; +// +// comp.parseOptions(); +// +// let value = {target:{value:'2016-08-22'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// value = {target:{value:'2016-08-2'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// value = {target:{value:'16.09/2016'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// value = {target:{value:'2016-08-xx'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// value = {target:{value:'16.09.999'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// value = {target:{value:'16.09.19999'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// value = {target:{value:'16.09.2016'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(false); +// +// comp.options = {dateFormat: 'dd mmm yyyy', indicateInvalidDate: true}; +// +// comp.parseOptions(); +// +// value = {target:{value:'2016-08-22'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(true); +// +// value = {target:{value:'22 Aug 2016'}}; +// comp.userDateInput(value); +// expect(comp.invalidDate).toBe(false); +// }); +// +// it('options - show today button', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// +// btnpicker.nativeElement.click(); +// +// comp.options = {showTodayBtn: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).toBe(null); +// +// btnpicker.nativeElement.click(); +// +// comp.options = {showTodayBtn: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// }); +// +// it('options - today button text', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// comp.options = {todayBtnTxt: 'test text'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// expect(headertodaybtn.nativeElement.textContent).toBe('test text'); +// }); +// +// it('options - first day of week', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// comp.options = {firstDayOfWeek: 'tu'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let first = getElement('.caltable thead tr th:first-child'); +// expect(first).not.toBe(null); +// expect(first.nativeElement.textContent).toBe('Tue'); +// +// let last = getElement('.caltable thead tr th:last-child'); +// expect(last).not.toBe(null); +// expect(last.nativeElement.textContent).toBe('Mon'); +// }); +// +// it('options - sunday highlight', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// comp.options = {sunHighlight: true}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let sunday = getElement('.sunday'); +// expect(sunday).not.toBe(null); +// +// btnpicker.nativeElement.click(); +// +// comp.options = {sunHighlight: false}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// sunday = getElement('.sunday'); +// expect(sunday).toBe(null); +// }); +// +// it('options - current day marked', () => { +// comp.options = {markCurrentDay: true}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// +// btnpicker.nativeElement.click(); +// +// comp.options = {markCurrentDay: false}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// currday = getElement('.currday'); +// expect(currday).toBe(null); +// }); +// +// it('options - editable month and year', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// comp.options = {editableMonthAndYear: true}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// montlabel.nativeElement.click(); +// +// fixture.detectChanges(); +// let monthinput = getElement('.monthinput'); +// expect(monthinput).not.toBe(null); +// +// comp.userMonthInput({target:{value:'jan'}}); +// +// fixture.detectChanges(); +// montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('Jan'); +// +// +// fixture.detectChanges(); +// let yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// yearlabel.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearinput = getElement('.yearinput'); +// expect(yearinput).not.toBe(null); +// +// comp.userYearInput({target:{value:'2019'}}); +// +// fixture.detectChanges(); +// yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent).toBe('2019'); +// }); +// +// it('options - disable header buttons', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 5, year: 2016}; +// comp.options = { +// disableHeaderButtons: true, +// disableUntil: {year: 2016, month: 4, day: 10} +// }; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('May'); +// +// fixture.detectChanges(); +// let prevmonth = getElement(PREVMONTH); +// expect(prevmonth).not.toBe(null); +// prevmonth.nativeElement.click(); +// +// fixture.detectChanges(); +// montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('Apr'); +// +// fixture.detectChanges(); +// let headerbtndisabled = getElements('.headerbtndisabled'); +// expect(headerbtndisabled).not.toBe(null); +// expect(headerbtndisabled.length).toBe(2); +// +// prevmonth.nativeElement.click(); +// +// fixture.detectChanges(); +// montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('Apr'); +// +// fixture.detectChanges(); +// let prevyear = getElement(PREVYEAR); +// expect(prevyear).not.toBe(null); +// prevyear.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent).toBe('2016'); +// +// btnpicker.nativeElement.click(); +// +// +// comp.options = { +// disableHeaderButtons: true, +// disableSince: {year: 2016, month: 7, day: 10} +// }; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('May'); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// nextmonth.nativeElement.click(); +// +// fixture.detectChanges(); +// montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('Jun'); +// +// fixture.detectChanges(); +// headerbtndisabled = getElements('.headerbtndisabled'); +// expect(headerbtndisabled).not.toBe(null); +// expect(headerbtndisabled.length).toBe(2); +// +// prevmonth.nativeElement.click(); +// +// fixture.detectChanges(); +// montlabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(montlabel).not.toBe(null); +// expect(montlabel.nativeElement.textContent).toBe('Jun'); +// +// fixture.detectChanges(); +// let nextyear = getElement(NEXTYEAR); +// expect(nextyear).not.toBe(null); +// nextyear.nativeElement.click(); +// +// fixture.detectChanges(); +// yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent).toBe('2016'); +// }); +// +// it('options - min year', () => { +// comp.visibleMonth = {monthTxt: 'May', monthNbr: 5, year: 2016}; +// comp.options = {minYear: 2000}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// yearlabel.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearinput = getElement('.yearinput'); +// expect(yearinput).not.toBe(null); +// +// comp.userYearInput({target:{value:1999}}); +// +// fixture.detectChanges(); +// let invalidyear = getElement('.invalidyear'); +// expect(invalidyear).not.toBe(null); +// +// comp.userYearInput({target:{value:2000}}); +// +// fixture.detectChanges(); +// yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent).toBe('2000'); +// }); +// +// it('options - max year', () => { +// comp.visibleMonth = {monthTxt: 'May', monthNbr: 5, year: 2016}; +// comp.options = {maxYear: 2020}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// yearlabel.nativeElement.click(); +// +// fixture.detectChanges(); +// let yearinput = getElement('.yearinput'); +// expect(yearinput).not.toBe(null); +// +// comp.userYearInput({target:{value:2021}}); +// +// fixture.detectChanges(); +// let invalidyear = getElement('.invalidyear'); +// expect(invalidyear).not.toBe(null); +// +// comp.userYearInput({target:{value:2020}}); +// +// fixture.detectChanges(); +// yearlabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearlabel).not.toBe(null); +// expect(yearlabel.nativeElement.textContent).toBe('2020'); +// }); +// +// it('options - disable until', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {disableUntil: {year: 2016, month: 10, day: 5}}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// let disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(10); +// +// let firstDisabled = disabled[0]; +// expect(firstDisabled.nativeElement.textContent.trim()).toBe('26'); +// +// let lastDisabled = disabled[disabled.length - 1]; +// expect(lastDisabled.nativeElement.textContent.trim()).toBe('5'); +// +// fixture.detectChanges(); +// lastDisabled.nativeElement.click(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe(''); +// +// fixture.detectChanges(); +// let selectableDays = getElements('.tablesingleday'); +// expect(selectableDays).not.toBe(null); +// expect(selectableDays.length).toBe(26); +// +// selectableDays[0].nativeElement.click(); +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain('2016-10-06'); +// }); +// +// it('options - disable since', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {disableSince: {year: 2016, month: 10, day: 30}}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// let disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(8); +// +// let firstDisabled = disabled[0]; +// expect(firstDisabled.nativeElement.textContent.trim()).toBe('30'); +// +// let lastDisabled = disabled[disabled.length - 1]; +// expect(lastDisabled.nativeElement.textContent.trim()).toBe('6'); +// +// fixture.detectChanges(); +// lastDisabled.nativeElement.click(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe(''); +// +// fixture.detectChanges(); +// let selectableDays = getElements('.tablesingleday'); +// expect(selectableDays).not.toBe(null); +// expect(selectableDays.length).toBe(29); +// +// selectableDays[5].nativeElement.click(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain('2016-10-06'); +// }); +// +// it('options - disable days one by one', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {disableDays: [{year: 2016, month: 10, day: 5}, {year: 2016, month: 10, day: 10}]}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// let disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(2); +// +// let firstDisabled = disabled[0]; +// expect(firstDisabled.nativeElement.textContent.trim()).toBe('5'); +// +// let lastDisabled = disabled[1]; +// expect(lastDisabled.nativeElement.textContent.trim()).toBe('10'); +// }); +// +// it('options - enable disabled days one by one', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2017}; +// comp.options = { +// dateFormat: 'dd.mm.yyyy', +// disableDateRange: {begin: {year: 2017, month: 1, day: 1}, end: {year: 2017, month: 1, day: 31}}, +// enableDays: [{year: 2017, month: 1, day: 5}, {year: 2017, month: 1, day: 6}, {year: 2017, month: 1, day: 7}, {year: 2017, month: 1, day: 8}] +// }; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(1, 2017, true); +// +// fixture.detectChanges(); +// let disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(27); +// +// let firstDisabled = disabled[0]; +// expect(firstDisabled.nativeElement.textContent.trim()).toBe('1'); +// +// let lastDisabled = disabled[disabled.length - 1]; +// expect(lastDisabled.nativeElement.textContent.trim()).toBe('31'); +// +// fixture.detectChanges(); +// let alldates = getElements('.caltable .daycell'); +// expect(alldates).not.toBe(null); +// expect(alldates.length).toBe(42); +// +// fixture.detectChanges(); +// let firstEnabled = alldates[10]; +// firstEnabled.nativeElement.click(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.nativeElement.value).toBe('05.01.2017'); +// }); +// +// it('options - disable range', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {disableDateRange: {begin: {year: 2016, month: 10, day: 5}, end: {year: 2016, month: 10, day: 10}}}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// let disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(6); +// +// let firstDisabled = disabled[0]; +// expect(firstDisabled.nativeElement.textContent.trim()).toBe('5'); +// +// let lastDisabled = disabled[disabled.length - 1]; +// expect(lastDisabled.nativeElement.textContent.trim()).toBe('10'); +// btnpicker.nativeElement.click(); +// +// +// comp.options = {disableDateRange: {begin: {}, end: {}}}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(0); +// }); +// +// it('options - disable today - today button disabled', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// +// let date = new Date(); +// comp.options = {disableDays: [{year: date.getFullYear(), month: date.getMonth() + 1, day: date.getDate()}]}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// let headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// expect(headertodaybtn.properties['disabled']).toBe(true); +// +// fixture.detectChanges(); +// headertodaybtn.nativeElement.click(); +// let selector = getElement('.selector'); +// expect(selector).not.toBe(null); +// +// btnpicker.nativeElement.click(); +// +// comp.options = {disableDays: []}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker.nativeElement.click(); +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// expect(headertodaybtn.properties['disabled']).toBe(false); +// +// headertodaybtn.nativeElement.click(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.nativeElement.value).toBe(getDateString(date)); +// }); +// +// it('options - disable weekends', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {firstDayOfWeek: 'mo', disableWeekends: true}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.generateCalendar(10, 2016, true); +// +// fixture.detectChanges(); +// let disabled = getElements('tr .disabled'); +// expect(disabled).not.toBe(null); +// expect(disabled.length).toBe(12); +// +// let firstDisabled = disabled[0]; +// expect(firstDisabled.nativeElement.textContent.trim()).toBe('1'); +// +// let secondDisabled = disabled[1]; +// expect(secondDisabled.nativeElement.textContent.trim()).toBe('2'); +// +// let lastDisabled = disabled[disabled.length - 1]; +// expect(lastDisabled.nativeElement.textContent.trim()).toBe('6'); +// +// fixture.detectChanges(); +// firstDisabled.nativeElement.click(); +// let selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe(''); +// +// fixture.detectChanges(); +// secondDisabled.nativeElement.click(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe(''); +// +// fixture.detectChanges(); +// let selectableDays = getElements('.tablesingleday'); +// expect(selectableDays).not.toBe(null); +// expect(selectableDays.length).toBe(21); +// +// selectableDays[0].nativeElement.click(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toContain('2016-10-03'); +// }); +// +// it('options - inline', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {inline: true}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selector = getElement('.selector'); +// expect(selector).not.toBe(null); +// +// fixture.detectChanges(); +// let selectiongroup = getElement('.selectiongroup'); +// expect(selectiongroup).toBe(null); +// }); +// +// it('options - show clear date button', () => { +// let date = new Date(); +// comp.selectedMonth = {monthTxt: '', monthNbr: date.getMonth() + 1, year: date.getFullYear()}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// +// currday.nativeElement.click(); +// +// fixture.detectChanges(); +// let btnclear = getElement('.btnclear'); +// expect(btnclear).not.toBe(null); +// +// btnclear.nativeElement.click(); +// +// comp.options = {showClearDateBtn: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// +// currday.nativeElement.click(); +// +// fixture.detectChanges(); +// btnclear = getElement('.btnclear'); +// expect(btnclear).not.toBe(null); +// btnclear.nativeElement.click(); +// +// btnclear.nativeElement.click(); +// +// +// comp.options = {showClearDateBtn: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// currday = getElement('.currday'); +// expect(currday).not.toBe(null); +// +// currday.nativeElement.click(); +// +// fixture.detectChanges(); +// btnclear = getElement('.btnclear'); +// expect(btnclear).toBe(null); +// }); +// +// it('options - height', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {height: '50px'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.styles['height']).toBe('50px'); +// }); +// +// it('options - width', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {width: '300px'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// expect(de).not.toBe(null); +// expect(de.styles['width']).toBe('300px'); +// +// comp.options = {width: '20%'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// expect(de).not.toBe(null); +// expect(de.styles['width']).toBe('20%'); +// }); +// +// it('options - selection text font size', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {selectionTxtFontSize: '10px'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.styles['font-size']).toBe('10px'); +// }); +// +// it('options - align selector right', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {alignSelectorRight: true}; +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let alignselectorright = getElement('.alignselectorright'); +// expect(alignselectorright).not.toBe(null); +// +// comp.options = {alignSelectorRight: false}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// alignselectorright = getElement('.alignselectorright'); +// expect(alignselectorright).toBe(null); +// }); +// +// it('options - open selector top of input', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {openSelectorTopOfInput: true, height: '30px'}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// let value: string = comp.getSelectorTopPosition(); +// expect(value).not.toBe(null); +// expect(value).toBe('32px'); +// +// btnpicker.nativeElement.click(); +// +// +// comp.options = {openSelectorTopOfInput: false}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// value = comp.getSelectorTopPosition(); +// expect(value).toBe(undefined); +// +// +// btnpicker.nativeElement.click(); +// +// comp.options = {}; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// value = comp.getSelectorTopPosition(); +// expect(value).toBe(undefined); +// }); +// +// it('options - indicate invalid date', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {indicateInvalidDate: true, dateFormat: 'dd.mm.yyyy'}; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'2016-08-22'}}); +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'2016-08-xx'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'2016-08-99'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'10.10.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// it('options - disableUntil input dates validation', ()=> { +// comp.options = { +// indicateInvalidDate: true, +// dateFormat: 'dd.mm.yyyy', +// disableUntil:{year: 2016, month: 11, day: 4} +// }; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'11.12.2015'}}); +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'11.06.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'04.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'05.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// +// comp.options = { +// indicateInvalidDate: true, +// dateFormat: 'dd.mm.yyyy', +// disableUntil:{year: 0, month: 0, day: 0} +// }; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'11.12.2015'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// it('options - disableSince input dates validation', ()=> { +// comp.options = { +// indicateInvalidDate: true, +// dateFormat: 'dd.mm.yyyy', +// disableSince:{year: 2016, month: 11, day: 22} +// }; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'08.12.2017'}}); +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'08.12.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'23.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'21.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// +// comp.options = { +// indicateInvalidDate: true, +// dateFormat: 'dd.mm.yyyy', +// disableSince:{year: 0, month: 0, day: 0} +// }; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'11.12.2015'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// it('options - disable weekends input date validation', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 11, year: 2016}; +// comp.options = { +// indicateInvalidDate: true, +// dateFormat: 'dd.mm.yyyy', +// disableWeekends: true, +// firstDayOfWeek: 'mo' +// }; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'05.11.2016'}}); +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'06.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'12.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'13.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'19.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'20.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'26.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'27.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'04.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// it('options - disableDays input date validation', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 11, year: 2016}; +// comp.options = { +// indicateInvalidDate: true, +// dateFormat: 'dd.mm.yyyy', +// disableDays: [ +// {year: 2016, month: 11, day: 1}, +// {year: 2016, month: 11, day: 3}, +// {year: 2016, month: 11, day: 5}, +// {year: 2016, month: 11, day: 7} +// ], +// firstDayOfWeek: 'mo' +// }; +// +// comp.parseOptions(); +// +// comp.userDateInput({target:{value:'01.11.2016'}}); +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'03.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'05.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'07.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).not.toBe(null); +// +// comp.userDateInput({target:{value:'02.11.2016'}}); +// fixture.detectChanges(); +// invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// it('options - disable component', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {componentDisabled: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// +// btnpicker.nativeElement.click(); +// fixture.detectChanges(); +// +// let selector = getElement('.selector'); +// expect(selector).toBe(null); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// +// selection.nativeElement.value = '2016-11-14'; +// +// fixture.detectChanges(); +// expect(selection.nativeElement.value).toContain(''); +// }); +// +// it('options - editable date field', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {editableDateField: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// +// selection.nativeElement.value = '2016-11-14'; +// +// fixture.detectChanges(); +// expect(selection.nativeElement.value).toContain(''); +// +// comp.options = {editableDateField: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// +// selection.nativeElement.value = '2016-11-14'; +// +// fixture.detectChanges(); +// expect(selection.nativeElement.value).toContain('2016-11-14'); +// }); +// +// it('options - click input to open selector', () => { +// +// let selection: DebugElement, +// selector: DebugElement; +// +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {editableDateField: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// +// selection.nativeElement.click(); +// +// fixture.detectChanges(); +// selector = getElement('.selector'); +// expect(selector).toBe(null); +// +// comp.options = {editableDateField: false, openSelectorOnInputClick: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// +// selection.nativeElement.click(); +// +// fixture.detectChanges(); +// selector = getElement('.selector'); +// expect(selector).not.toBe(null); +// }); +// +// it('options - input field value required', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.properties['required']).toBe(false); +// +// comp.options = {inputValueRequired: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.properties['required']).toBe(true); +// +// comp.options = {inputValueRequired: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.properties['required']).toBe(false); +// }); +// +// it('options - show selector arrow', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let selectorarrow = getElement('.selectorarrow'); +// expect(selectorarrow).not.toBe(null); +// btnpicker.nativeElement.click(); +// +// +// comp.options = {showSelectorArrow: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// selectorarrow = getElement('.selectorarrow'); +// expect(selectorarrow).toBe(null); +// btnpicker.nativeElement.click(); +// +// +// comp.options = {showSelectorArrow: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// selectorarrow = getElement('.selectorarrow'); +// expect(selectorarrow).not.toBe(null); +// btnpicker.nativeElement.click(); +// }); +// +// it('options - show input field', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 10, year: 2016}; +// comp.options = {}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// +// +// comp.options = {showInputField: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection).toBe(null); +// +// +// comp.options = {showInputField: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// }); +// +// it('options - input auto fill', () => { +// comp.options = {inputAutoFill: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// +// fixture.detectChanges(); +// selection.nativeElement.value = '2016-2-1'; +// fixture.nativeElement.querySelector('.selection').dispatchEvent(new Event('keyup')); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe('2016-2-1'); +// +// +// comp.options = {inputAutoFill: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// selection.nativeElement.value = ''; +// +// fixture.detectChanges(); +// selection.nativeElement.value = '2016-1-'; +// fixture.nativeElement.querySelector('.selection').dispatchEvent(new Event('keyup')); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe('2016-01-'); +// +// fixture.detectChanges(); +// selection.nativeElement.value = '2016-01-9'; +// fixture.nativeElement.querySelector('.selection').dispatchEvent(new Event('keyup')); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection.nativeElement.value).toBe('2016-01-09'); +// }); +// +// it('options - show week numbers', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2017}; +// comp.options = {showWeekNumbers: false}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let weekdaytitleweeknbr = getElement('.weekdaytitleweeknbr'); +// expect(weekdaytitleweeknbr).toBe(null); +// +// fixture.detectChanges(); +// let daycellweeknbr = getElements('.daycellweeknbr'); +// expect(daycellweeknbr.length).toBe(0); +// +// btnpicker.nativeElement.click(); +// +// +// comp.options = {showWeekNumbers: true}; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// weekdaytitleweeknbr = getElement('.weekdaytitleweeknbr'); +// expect(weekdaytitleweeknbr).not.toBe(null); +// +// fixture.detectChanges(); +// daycellweeknbr = getElements('.daycellweeknbr'); +// expect(daycellweeknbr.length).toBe(6); +// +// expect(daycellweeknbr[0].nativeElement.textContent.trim()).toBe('52'); +// expect(daycellweeknbr[1].nativeElement.textContent.trim()).toBe('1'); +// expect(daycellweeknbr[2].nativeElement.textContent.trim()).toBe('2'); +// expect(daycellweeknbr[3].nativeElement.textContent.trim()).toBe('3'); +// expect(daycellweeknbr[4].nativeElement.textContent.trim()).toBe('4'); +// expect(daycellweeknbr[5].nativeElement.textContent.trim()).toBe('5'); +// +// fixture.detectChanges(); +// let prevyear = getElement(PREVYEAR); +// expect(prevyear).not.toBe(null); +// prevyear.nativeElement.click(); +// +// fixture.detectChanges(); +// daycellweeknbr = getElements('.daycellweeknbr'); +// expect(daycellweeknbr.length).toBe(6); +// +// expect(daycellweeknbr[0].nativeElement.textContent.trim()).toBe('53'); +// expect(daycellweeknbr[1].nativeElement.textContent.trim()).toBe('1'); +// expect(daycellweeknbr[2].nativeElement.textContent.trim()).toBe('2'); +// expect(daycellweeknbr[3].nativeElement.textContent.trim()).toBe('3'); +// expect(daycellweeknbr[4].nativeElement.textContent.trim()).toBe('4'); +// expect(daycellweeknbr[5].nativeElement.textContent.trim()).toBe('5'); +// +// prevyear.nativeElement.click(); +// +// fixture.detectChanges(); +// daycellweeknbr = getElements('.daycellweeknbr'); +// expect(daycellweeknbr.length).toBe(6); +// +// expect(daycellweeknbr[0].nativeElement.textContent.trim()).toBe('1'); +// expect(daycellweeknbr[1].nativeElement.textContent.trim()).toBe('2'); +// expect(daycellweeknbr[2].nativeElement.textContent.trim()).toBe('3'); +// expect(daycellweeknbr[3].nativeElement.textContent.trim()).toBe('4'); +// expect(daycellweeknbr[4].nativeElement.textContent.trim()).toBe('5'); +// expect(daycellweeknbr[5].nativeElement.textContent.trim()).toBe('6'); +// }); +// +// it('options - aria label texts', () => { +// comp.selectedDate = comp.parseSelectedDate('2017-10-11'); +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// expect(btnpicker).not.toBe(null); +// expect(btnpicker.nativeElement.attributes['aria-label'].textContent).toBe('Open Calendar'); +// +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.nativeElement.attributes['aria-label'].textContent).toBe('Date input field'); +// +// fixture.detectChanges(); +// let btnclear = getElement('.btnclear'); +// expect(btnclear).not.toBe(null); +// expect(btnclear.nativeElement.attributes['aria-label'].textContent).toBe('Clear Date'); +// +// +// fixture.detectChanges(); +// let prevmonth = getElement(PREVMONTH); +// expect(prevmonth).not.toBe(null); +// expect(prevmonth.nativeElement.attributes['aria-label'].textContent).toBe('Previous Month'); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// expect(nextmonth.nativeElement.attributes['aria-label'].textContent).toBe('Next Month'); +// +// fixture.detectChanges(); +// let prevyear = getElement(PREVYEAR); +// expect(prevyear).not.toBe(null); +// expect(prevyear.nativeElement.attributes['aria-label'].textContent).toBe('Previous Year'); +// +// fixture.detectChanges(); +// let nextyear = getElement(NEXTYEAR); +// expect(nextyear).not.toBe(null); +// expect(nextyear.nativeElement.attributes['aria-label'].textContent).toBe('Next Year'); +// +// btnpicker.nativeElement.click(); +// +// comp.options = { +// ariaLabelInputField: 'text 1', +// ariaLabelClearDate: 'text 2', +// ariaLabelOpenCalendar: 'text 3', +// ariaLabelPrevMonth: 'text 4', +// ariaLabelNextMonth: 'text 5', +// ariaLabelPrevYear: 'text 6', +// ariaLabelNextYear: 'text 7' +// }; +// comp.parseOptions(); +// +// fixture.detectChanges(); +// btnpicker = getElement('.btnpicker'); +// expect(btnpicker).not.toBe(null); +// expect(btnpicker.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelOpenCalendar); +// +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelInputField); +// +// fixture.detectChanges(); +// btnclear = getElement('.btnclear'); +// expect(btnclear).not.toBe(null); +// expect(btnclear.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelClearDate); +// +// +// fixture.detectChanges(); +// prevmonth = getElement(PREVMONTH); +// expect(prevmonth).not.toBe(null); +// expect(prevmonth.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelPrevMonth); +// +// fixture.detectChanges(); +// nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// expect(nextmonth.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelNextMonth); +// +// fixture.detectChanges(); +// prevyear = getElement(PREVYEAR); +// expect(prevyear).not.toBe(null); +// expect(prevyear.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelPrevYear); +// +// fixture.detectChanges(); +// nextyear = getElement(NEXTYEAR); +// expect(nextyear).not.toBe(null); +// expect(nextyear.nativeElement.attributes['aria-label'].textContent).toBe(comp.options.ariaLabelNextYear); +// }); +// +// it('locale - use fr locale', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// comp.locale = 'fr'; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let days = getElements('.caltable thead tr th'); +// expect(days.length).toBe(7); +// expect(days[0].nativeElement.textContent).toBe('Lun'); +// expect(days[1].nativeElement.textContent).toBe('Mar'); +// expect(days[2].nativeElement.textContent).toBe('Mer'); +// expect(days[3].nativeElement.textContent).toBe('Jeu'); +// expect(days[4].nativeElement.textContent).toBe('Ven'); +// expect(days[5].nativeElement.textContent).toBe('Sam'); +// expect(days[6].nativeElement.textContent).toBe('Dim'); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// +// fixture.detectChanges(); +// let monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Jan'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Fév'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Mar'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Avr'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Mai'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Juin'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Juil'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Aoû'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Sep'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Oct'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Nov'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Déc'); +// +// fixture.detectChanges(); +// let headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// expect(headertodaybtn.nativeElement.textContent).toBe('Aujourd\'hui'); +// +// fixture.detectChanges(); +// let firstDayOfWeek = getElement('.caltable thead tr th:first-child'); +// expect(firstDayOfWeek).not.toBe(null); +// expect(firstDayOfWeek.nativeElement.textContent).toBe('Lun'); +// +// fixture.detectChanges(); +// let sunday = getElement('.sunday'); +// expect(sunday).not.toBe(null); +// +// comp.userDateInput({target:{value:'10/10/2016'}}); +// expect(comp.invalidDate).toBe(false); +// +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// it('selDate - initially selected date - string', () => { +// let date: string = '2017-10-11'; +// comp.selectedDate = comp.parseSelectedDate(date); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.nativeElement.value).toContain('2017-10-11'); +// +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let selectedday = getElement('.selectedday div span'); +// expect(selectedday).not.toBe(null); +// expect(selectedday.nativeElement.textContent).toContain('11'); +// +// fixture.detectChanges(); +// let monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel).not.toBe(null); +// expect(monthLabel.nativeElement.textContent).toBe('Oct'); +// +// fixture.detectChanges(); +// let yearLabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearLabel).not.toBe(null); +// expect(yearLabel.nativeElement.textContent).toBe('2017'); +// }); +// +// it('selDate - initially selected date - object', () => { +// let date: Object = {year: 2017, month: 10, day: 11}; +// comp.selectedDate = comp.parseSelectedDate(date); +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.nativeElement.value).toContain('2017-10-11'); +// expect(comp.selectionDayTxt).toContain('2017-10-11'); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let selectedday = getElement('.selectedday div span'); +// expect(selectedday).not.toBe(null); +// expect(selectedday.nativeElement.textContent).toContain('11'); +// +// fixture.detectChanges(); +// let monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel).not.toBe(null); +// expect(monthLabel.nativeElement.textContent).toBe('Oct'); +// +// fixture.detectChanges(); +// let yearLabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearLabel).not.toBe(null); +// expect(yearLabel.nativeElement.textContent).toBe('2017'); +// }); +// +// it('defaultMonth - initially selected month', () => { +// comp.selectedMonth = comp.parseSelectedMonth('2019-08'); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel).not.toBe(null); +// expect(monthLabel.nativeElement.textContent).toBe('Aug'); +// +// fixture.detectChanges(); +// let yearLabel = getElement('.headeryeartxt .headerlabelbtn'); +// expect(yearLabel).not.toBe(null); +// expect(yearLabel.nativeElement.textContent).toBe('2019'); +// }); +// +// it('placeholder - placeholder text', () => { +// comp.placeholder = ''; +// +// fixture.detectChanges(); +// let selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.properties['placeholder']).toBe(''); +// +// comp.placeholder = 'Select date'; +// +// fixture.detectChanges(); +// selection = getElement('.selection'); +// expect(selection).not.toBe(null); +// expect(selection.properties['placeholder']).toBe(comp.placeholder); +// +// +// }); +// +// it('locale - use id locale', () => { +// comp.selectedMonth = {monthTxt: '', monthNbr: 1, year: 2016}; +// comp.locale = 'id'; +// +// comp.parseOptions(); +// +// fixture.detectChanges(); +// let btnpicker = getElement('.btnpicker'); +// btnpicker.nativeElement.click(); +// +// fixture.detectChanges(); +// let days = getElements('.caltable thead tr th'); +// expect(days.length).toBe(7); +// expect(days[0].nativeElement.textContent).toBe('Min'); +// expect(days[1].nativeElement.textContent).toBe('Sen'); +// expect(days[2].nativeElement.textContent).toBe('Sel'); +// expect(days[3].nativeElement.textContent).toBe('Rab'); +// expect(days[4].nativeElement.textContent).toBe('Kam'); +// expect(days[5].nativeElement.textContent).toBe('Jum'); +// expect(days[6].nativeElement.textContent).toBe('Sab'); +// +// fixture.detectChanges(); +// let nextmonth = getElement(NEXTMONTH); +// expect(nextmonth).not.toBe(null); +// +// fixture.detectChanges(); +// let monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Jan'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Feb'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Mar'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Apr'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Mei'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Jun'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Jul'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Ags'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Sep'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Okt'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Nov'); +// +// nextmonth.nativeElement.click(); +// fixture.detectChanges(); +// monthLabel = getElement('.headermonthtxt .headerlabelbtn'); +// expect(monthLabel.nativeElement.textContent).toBe('Des'); +// +// fixture.detectChanges(); +// let headertodaybtn = getElement('.headertodaybtn'); +// expect(headertodaybtn).not.toBe(null); +// expect(headertodaybtn.nativeElement.textContent).toBe('Hari ini'); +// +// fixture.detectChanges(); +// let firstDayOfWeek = getElement('.caltable thead tr th:first-child'); +// expect(firstDayOfWeek).not.toBe(null); +// expect(firstDayOfWeek.nativeElement.textContent).toBe('Min'); +// +// fixture.detectChanges(); +// let sunday = getElement('.sunday'); +// expect(sunday).not.toBe(null); +// +// comp.userDateInput({target:{value:'10-10-2016'}}); +// expect(comp.invalidDate).toBe(false); +// +// fixture.detectChanges(); +// let invaliddate = getElement('.invaliddate'); +// expect(invaliddate).toBe(null); +// }); +// +// }); diff --git a/utils/my-date-picker/my-date-picker.component.ts b/utils/my-date-picker/my-date-picker.component.ts new file mode 100644 index 00000000..389a5be3 --- /dev/null +++ b/utils/my-date-picker/my-date-picker.component.ts @@ -0,0 +1,677 @@ +import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges, ElementRef, ViewEncapsulation, ChangeDetectorRef, Renderer, forwardRef } from "@angular/core"; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms"; +import { IMyDate, IMyDateRange, IMyMonth, IMyCalendarDay, IMyWeek, IMyDayLabels, IMyMonthLabels, IMyOptions, IMyDateModel, IMyInputAutoFill, IMyInputFieldChanged, IMyCalendarViewChanged, IMyInputFocusBlur } from "./interfaces/index"; +import { LocaleService } from "./services/my-date-picker.locale.service"; +import { UtilService } from "./services/my-date-picker.util.service"; + +// webpack1_ +declare var require: any; +// declare var myDpStyles: string = require("./my-date-picker.component.css"); +// declare var myDpTpl: string = require("./my-date-picker.component.html"); +// webpack2_ + +export const MYDP_VALUE_ACCESSOR: any = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => MyDatePicker), + multi: true +}; + +@Component({ + selector: "my-date-picker", + styleUrls: ['my-date-picker.component.css'], + templateUrl: 'my-date-picker.component.html', + providers: [LocaleService, UtilService, MYDP_VALUE_ACCESSOR], + encapsulation: ViewEncapsulation.None +}) + +export class MyDatePicker implements OnChanges, ControlValueAccessor { + @Input() options: any; + @Input() locale: string; + @Input() defaultMonth: string; + @Input() selDate: string; + @Input() placeholder: string; + @Input() selector: number; + @Output() dateChanged: EventEmitter = new EventEmitter(); + @Output() inputFieldChanged: EventEmitter = new EventEmitter(); + @Output() calendarViewChanged: EventEmitter = new EventEmitter(); + @Output() calendarToggle: EventEmitter = new EventEmitter(); + @Output() inputFocusBlur: EventEmitter = new EventEmitter(); + + onChangeCb: (_: any) => void = () => { }; + onTouchedCb: () => void = () => { }; + + showSelector: boolean = false; + visibleMonth: IMyMonth = {monthTxt: "", monthNbr: 0, year: 0}; + selectedMonth: IMyMonth = {monthTxt: "", monthNbr: 0, year: 0}; + selectedDate: IMyDate = {year: 0, month: 0, day: 0}; + weekDays: Array = []; + dates: Array = []; + selectionDayTxt: string = ""; + invalidDate: boolean = false; + disableTodayBtn: boolean = false; + dayIdx: number = 0; + weekDayOpts: Array = ["su", "mo", "tu", "we", "th", "fr", "sa"]; + autoFillOpts: IMyInputAutoFill = {separator: "", formatParts: [], enabled: true}; + + editMonth: boolean = false; + invalidMonth: boolean = false; + editYear: boolean = false; + invalidYear: boolean = false; + + prevMonthDisabled: boolean = false; + nextMonthDisabled: boolean = false; + prevYearDisabled: boolean = false; + nextYearDisabled: boolean = false; + + PREV_MONTH: number = 1; + CURR_MONTH: number = 2; + NEXT_MONTH: number = 3; + + MIN_YEAR: number = 1000; + MAX_YEAR: number = 9999; + + // Default options + opts: IMyOptions = { + dayLabels: {}, + monthLabels: {}, + dateFormat: "", + showTodayBtn: true, + todayBtnTxt: "", + firstDayOfWeek: "", + sunHighlight: true, + markCurrentDay: true, + disableUntil: {year: 0, month: 0, day: 0}, + disableSince: {year: 0, month: 0, day: 0}, + disableDays: > [], + enableDays: > [], + disableDateRange: {begin: {year: 0, month: 0, day: 0}, end: {year: 0, month: 0, day: 0}}, + disableWeekends: false, + showWeekNumbers: false, + height: "34px", + width: "100%", + selectionTxtFontSize: "18px", + inline: false, + showClearDateBtn: true, + alignSelectorRight: false, + openSelectorTopOfInput: false, + indicateInvalidDate: true, + editableDateField: true, + editableMonthAndYear: true, + disableHeaderButtons: true, + minYear: this.MIN_YEAR, + maxYear: this.MAX_YEAR, + componentDisabled: false, + inputValueRequired: false, + showSelectorArrow: true, + showInputField: true, + openSelectorOnInputClick: false, + inputAutoFill: true, + ariaLabelInputField: "Date input field", + ariaLabelClearDate: "Clear Date", + ariaLabelOpenCalendar: "Open Calendar", + ariaLabelPrevMonth: "Previous Month", + ariaLabelNextMonth: "Next Month", + ariaLabelPrevYear: "Previous Year", + ariaLabelNextYear: "Next Year" + }; + + constructor(public elem: ElementRef, private renderer: Renderer, private cdr: ChangeDetectorRef, private localeService: LocaleService, private utilService: UtilService) { + this.setLocaleOptions(); + renderer.listenGlobal("document", "click", (event: any) => { + if (this.showSelector && event.target && this.elem.nativeElement !== event.target && !this.elem.nativeElement.contains(event.target)) { + this.showSelector = false; + this.calendarToggle.emit(4); + } + if (this.opts.editableMonthAndYear && event.target && this.elem.nativeElement.contains(event.target)) { + this.resetMonthYearEdit(); + } + }); + } + + setLocaleOptions(): void { + let opts: IMyOptions = this.localeService.getLocaleOptions(this.locale); + Object.keys(opts).forEach((k) => { + (this.opts)[k] = opts[k]; + }); + } + + setOptions(): void { + if (this.options !== undefined) { + Object.keys(this.options).forEach((k) => { + (this.opts)[k] = this.options[k]; + }); + } + if (this.opts.minYear < this.MIN_YEAR) { + this.opts.minYear = this.MIN_YEAR; + } + if (this.opts.maxYear > this.MAX_YEAR) { + this.opts.maxYear = this.MAX_YEAR; + } + + let separator: string = this.utilService.getDateFormatSeparator(this.opts.dateFormat); + this.autoFillOpts = {separator: separator, formatParts: this.opts.dateFormat.split(separator), enabled: this.opts.inputAutoFill}; + } + + getComponentWidth(): string { + if (this.opts.showInputField) { + return this.opts.width; + } + else if (this.selectionDayTxt.length > 0 && this.opts.showClearDateBtn) { + return "60px"; + } + else { + return "30px"; + } + } + + getSelectorTopPosition(): string { + if (this.opts.openSelectorTopOfInput) { + return this.elem.nativeElement.children[0].offsetHeight + "px"; + } + } + + resetMonthYearEdit(): void { + this.editMonth = false; + this.editYear = false; + this.invalidMonth = false; + this.invalidYear = false; + } + + editMonthClicked(event: any): void { + event.stopPropagation(); + if (this.opts.editableMonthAndYear) { + this.editMonth = true; + } + } + + editYearClicked(event: any): void { + event.stopPropagation(); + if (this.opts.editableMonthAndYear) { + this.editYear = true; + } + } + + userDateInput(event: any): void { + this.invalidDate = false; + if (event.target.value.length === 0) { + this.clearDate(); + } + else { + let date: IMyDate = this.utilService.isDateValid(event.target.value, this.opts.dateFormat, this.opts.minYear, this.opts.maxYear, this.opts.disableUntil, this.opts.disableSince, this.opts.disableWeekends, this.opts.disableDays, this.opts.disableDateRange, this.opts.monthLabels, this.opts.enableDays); + if (date.day !== 0 && date.month !== 0 && date.year !== 0) { + this.selectDate(date); + } + else { + this.invalidDate = true; + } + } + if (this.invalidDate) { + this.inputFieldChanged.emit({value: event.target.value, dateFormat: this.opts.dateFormat, valid: !(event.target.value.length === 0 || this.invalidDate)}); + this.onChangeCb(""); + this.onTouchedCb(); + } + } + + onFocusInput(event: any): void { + this.inputFocusBlur.emit({reason: 1, value: event.target.value}); + } + + lostFocusInput(event: any): void { + this.selectionDayTxt = event.target.value; + this.onTouchedCb(); + this.inputFocusBlur.emit({reason: 2, value: event.target.value}); + } + + userMonthInput(event: any): void { + if (event.keyCode === 13 || event.keyCode === 37 || event.keyCode === 39) { + return; + } + + this.invalidMonth = false; + + let m: number = this.utilService.isMonthLabelValid(event.target.value, this.opts.monthLabels); + if (m !== -1) { + this.editMonth = false; + if (m !== this.visibleMonth.monthNbr) { + this.visibleMonth = {monthTxt: this.monthText(m), monthNbr: m, year: this.visibleMonth.year}; + this.generateCalendar(m, this.visibleMonth.year, true); + } + } + else { + this.invalidMonth = true; + } + } + + userYearInput(event: any): void { + if (event.keyCode === 13 || event.keyCode === 37 || event.keyCode === 39) { + return; + } + + this.invalidYear = false; + + let y: number = this.utilService.isYearLabelValid(Number(event.target.value), this.opts.minYear, this.opts.maxYear); + if (y !== -1) { + this.editYear = false; + if (y !== this.visibleMonth.year) { + this.visibleMonth = {monthTxt: this.visibleMonth.monthTxt, monthNbr: this.visibleMonth.monthNbr, year: y}; + this.generateCalendar(this.visibleMonth.monthNbr, y, true); + } + } + else { + this.invalidYear = true; + } + } + + isTodayDisabled(): void { + this.disableTodayBtn = this.utilService.isDisabledDay(this.getToday(), this.opts.disableUntil, this.opts.disableSince, this.opts.disableWeekends, this.opts.disableDays, this.opts.disableDateRange, this.opts.enableDays); + } + + parseOptions(): void { + if (this.locale) { + this.setLocaleOptions(); + } + this.setOptions(); + this.isTodayDisabled(); + this.dayIdx = this.weekDayOpts.indexOf(this.opts.firstDayOfWeek); + if (this.dayIdx !== -1) { + let idx: number = this.dayIdx; + for (let i = 0; i < this.weekDayOpts.length; i++) { + this.weekDays.push(this.opts.dayLabels[this.weekDayOpts[idx]]); + idx = this.weekDayOpts[idx] === "sa" ? 0 : idx + 1; + } + } + } + + writeValue(value: Object): void { + if (value && value["date"]) { + this.updateDateValue(this.parseSelectedDate(value["date"]), false); + } + else if (value === "") { + this.updateDateValue({year: 0, month: 0, day: 0}, true); + } + } + + registerOnChange(fn: any): void { + this.onChangeCb = fn; + } + + registerOnTouched(fn: any): void { + this.onTouchedCb = fn; + } + + ngOnChanges(changes: SimpleChanges): void { + if (changes.hasOwnProperty("selector") && changes["selector"].currentValue > 0) { + this.openBtnClicked(); + } + + if (changes.hasOwnProperty("placeholder")) { + this.placeholder = changes["placeholder"].currentValue; + } + + if (changes.hasOwnProperty("locale")) { + this.locale = changes["locale"].currentValue; + } + + if (changes.hasOwnProperty("options")) { + this.options = changes["options"].currentValue; + } + + this.weekDays.length = 0; + this.parseOptions(); + + if (changes.hasOwnProperty("defaultMonth")) { + let dm: string = changes["defaultMonth"].currentValue; + if (dm !== null && dm !== undefined && dm !== "") { + this.selectedMonth = this.parseSelectedMonth(dm); + } + else { + this.selectedMonth = {monthTxt: "", monthNbr: 0, year: 0}; + } + } + + if (changes.hasOwnProperty("selDate")) { + let sd: any = changes["selDate"]; + if (sd.currentValue !== null && sd.currentValue !== undefined && sd.currentValue !== "" && Object.keys(sd.currentValue).length !== 0) { + this.selectedDate = this.parseSelectedDate(sd.currentValue); + setTimeout(() => { + this.onChangeCb(this.getDateModel(this.selectedDate)); + }); + } + else { + // Do not clear on init + if (!sd.isFirstChange()) { + this.clearDate(); + } + } + } + if (this.opts.inline) { + this.setVisibleMonth(); + } + else if (this.showSelector) { + this.generateCalendar(this.visibleMonth.monthNbr, this.visibleMonth.year, false); + } + } + + removeBtnClicked(): void { + // Remove date button clicked + this.clearDate(); + if (this.showSelector) { + this.calendarToggle.emit(3); + } + this.showSelector = false; + } + + openBtnClicked(): void { + // Open selector button clicked + this.showSelector = !this.showSelector; + if (this.showSelector) { + this.setVisibleMonth(); + this.calendarToggle.emit(1); + } + else { + this.calendarToggle.emit(3); + } + } + + setVisibleMonth(): void { + // Sets visible month of calendar + let y: number = 0, m: number = 0; + if (!this.utilService.isInitializedDate(this.selectedDate)) { + if (this.selectedMonth.year === 0 && this.selectedMonth.monthNbr === 0) { + let today: IMyDate = this.getToday(); + y = today.year; + m = today.month; + } else { + y = this.selectedMonth.year; + m = this.selectedMonth.monthNbr; + } + } + else { + y = this.selectedDate.year; + m = this.selectedDate.month; + } + this.visibleMonth = {monthTxt: this.opts.monthLabels[m], monthNbr: m, year: y}; + + // Create current month + this.generateCalendar(m, y, true); + } + + prevMonth(): void { + // Previous month from calendar + let d: Date = this.getDate(this.visibleMonth.year, this.visibleMonth.monthNbr, 1); + d.setMonth(d.getMonth() - 1); + + let y: number = d.getFullYear(); + let m: number = d.getMonth() + 1; + + this.visibleMonth = {monthTxt: this.monthText(m), monthNbr: m, year: y}; + this.generateCalendar(m, y, true); + } + + nextMonth(): void { + // Next month from calendar + let d: Date = this.getDate(this.visibleMonth.year, this.visibleMonth.monthNbr, 1); + d.setMonth(d.getMonth() + 1); + + let y: number = d.getFullYear(); + let m: number = d.getMonth() + 1; + + this.visibleMonth = {monthTxt: this.monthText(m), monthNbr: m, year: y}; + this.generateCalendar(m, y, true); + } + + prevYear(): void { + // Previous year from calendar + this.visibleMonth.year--; + this.generateCalendar(this.visibleMonth.monthNbr, this.visibleMonth.year, true); + } + + nextYear(): void { + // Next year from calendar + this.visibleMonth.year++; + this.generateCalendar(this.visibleMonth.monthNbr, this.visibleMonth.year, true); + } + + todayClicked(): void { + // Today button clicked + let today: IMyDate = this.getToday(); + this.selectDate(today); + if (this.opts.inline && today.year !== this.visibleMonth.year || today.month !== this.visibleMonth.monthNbr) { + this.visibleMonth = {monthTxt: this.opts.monthLabels[today.month], monthNbr: today.month, year: today.year}; + this.generateCalendar(today.month, today.year, true); + } + } + + cellClicked(cell: any): void { + // Cell clicked on the calendar + if (cell.cmo === this.PREV_MONTH) { + // Previous month day + this.prevMonth(); + } + else if (cell.cmo === this.CURR_MONTH) { + // Current month day - if date is already selected clear it + if (cell.dateObj.year === this.selectedDate.year && cell.dateObj.month === this.selectedDate.month && cell.dateObj.day === this.selectedDate.day) { + this.clearDate(); + } + else { + this.selectDate(cell.dateObj); + } + } + else if (cell.cmo === this.NEXT_MONTH) { + // Next month day + this.nextMonth(); + } + this.resetMonthYearEdit(); + } + + cellKeyDown(event: any, cell: any) { + // Cell keyboard handling + if ((event.keyCode === 13 || event.keyCode === 32) && !cell.disabled) { + event.preventDefault(); + this.cellClicked(cell); + } + } + + clearDate(): void { + // Clears the date and notifies parent using callbacks and value accessor + let date: IMyDate = {year: 0, month: 0, day: 0}; + this.dateChanged.emit({date: date, jsdate: null, formatted: "", epoc: 0}); + this.onChangeCb(""); + this.onTouchedCb(); + this.updateDateValue(date, true); + } + + selectDate(date: IMyDate): void { + // Date selected, notifies parent using callbacks and value accessor + let dateModel: IMyDateModel = this.getDateModel(date); + this.dateChanged.emit(dateModel); + this.onChangeCb(dateModel); + this.onTouchedCb(); + this.updateDateValue(date, false); + if (this.showSelector) { + this.calendarToggle.emit(2); + } + this.showSelector = false; + } + + updateDateValue(date: IMyDate, clear: boolean): void { + // Updates date values + this.selectedDate = date; + this.selectionDayTxt = clear ? "" : this.formatDate(date); + this.inputFieldChanged.emit({value: this.selectionDayTxt, dateFormat: this.opts.dateFormat, valid: !clear}); + this.invalidDate = false; + } + + getDateModel(date: IMyDate): IMyDateModel { + // Creates a date model object from the given parameter + return {date: date, jsdate: this.getDate(date.year, date.month, date.day), formatted: this.formatDate(date), epoc: Math.round(this.getTimeInMilliseconds(date) / 1000.0)}; + } + + preZero(val: string): string { + // Prepend zero if smaller than 10 + return parseInt(val) < 10 ? "0" + val : val; + } + + formatDate(val: any): string { + // Returns formatted date string, if mmm is part of dateFormat returns month as a string + let formatted: string = this.opts.dateFormat.replace("yyyy", val.year).replace("dd", this.preZero(val.day)); + return this.opts.dateFormat.indexOf("mmm") !== -1 ? formatted.replace("mmm", this.monthText(val.month)) : formatted.replace("mm", this.preZero(val.month)); + } + + monthText(m: number): string { + // Returns month as a text + return this.opts.monthLabels[m]; + } + + monthStartIdx(y: number, m: number): number { + // Month start index + let d = new Date(); + d.setDate(1); + d.setMonth(m - 1); + d.setFullYear(y); + let idx = d.getDay() + this.sundayIdx(); + return idx >= 7 ? idx - 7 : idx; + } + + daysInMonth(m: number, y: number): number { + // Return number of days of current month + return new Date(y, m, 0).getDate(); + } + + daysInPrevMonth(m: number, y: number): number { + // Return number of days of the previous month + let d: Date = this.getDate(y, m, 1); + d.setMonth(d.getMonth() - 1); + return this.daysInMonth(d.getMonth() + 1, d.getFullYear()); + } + + isCurrDay(d: number, m: number, y: number, cmo: number, today: IMyDate): boolean { + // Check is a given date the today + return d === today.day && m === today.month && y === today.year && cmo === this.CURR_MONTH; + } + + getToday(): IMyDate { + let date: Date = new Date(); + return {year: date.getFullYear(), month: date.getMonth() + 1, day: date.getDate()}; + } + + getTimeInMilliseconds(date: IMyDate): number { + return this.getDate(date.year, date.month, date.day).getTime(); + } + + getDayNumber(date: IMyDate): number { + // Get day number: su=0, mo=1, tu=2, we=3 ... + let d: Date = this.getDate(date.year, date.month, date.day); + return d.getDay(); + } + + getWeekday(date: IMyDate): string { + // Get weekday: su, mo, tu, we ... + return this.weekDayOpts[this.getDayNumber(date)]; + } + + getDate(year: number, month: number, day: number): Date { + // Creates a date object from given year, month and day + return new Date(year, month - 1, day, 0, 0, 0, 0); + } + + sundayIdx(): number { + // Index of Sunday day + return this.dayIdx > 0 ? 7 - this.dayIdx : 0; + } + + generateCalendar(m: number, y: number, notifyChange: boolean): void { + this.dates.length = 0; + let today: IMyDate = this.getToday(); + let monthStart: number = this.monthStartIdx(y, m); + let dInThisM: number = this.daysInMonth(m, y); + let dInPrevM: number = this.daysInPrevMonth(m, y); + + let dayNbr: number = 1; + let cmo: number = this.PREV_MONTH; + for (let i = 1; i < 7; i++) { + let week: Array = []; + if (i === 1) { + // First week + let pm = dInPrevM - monthStart + 1; + // Previous month + for (let j = pm; j <= dInPrevM; j++) { + let date: IMyDate = {year: y, month: m - 1, day: j}; + week.push({dateObj: date, cmo: cmo, currDay: this.isCurrDay(j, m, y, cmo, today), dayNbr: this.getDayNumber(date), disabled: this.utilService.isDisabledDay(date, this.opts.disableUntil, this.opts.disableSince, this.opts.disableWeekends, this.opts.disableDays, this.opts.disableDateRange, this.opts.enableDays)}); + } + + cmo = this.CURR_MONTH; + // Current month + let daysLeft: number = 7 - week.length; + for (let j = 0; j < daysLeft; j++) { + let date: IMyDate = {year: y, month: m, day: dayNbr}; + week.push({dateObj: date, cmo: cmo, currDay: this.isCurrDay(dayNbr, m, y, cmo, today), dayNbr: this.getDayNumber(date), disabled: this.utilService.isDisabledDay(date, this.opts.disableUntil, this.opts.disableSince, this.opts.disableWeekends, this.opts.disableDays, this.opts.disableDateRange, this.opts.enableDays)}); + dayNbr++; + } + } + else { + // Rest of the weeks + for (let j = 1; j < 8; j++) { + if (dayNbr > dInThisM) { + // Next month + dayNbr = 1; + cmo = this.NEXT_MONTH; + } + let date: IMyDate = {year: y, month: cmo === this.CURR_MONTH ? m : m + 1, day: dayNbr}; + week.push({dateObj: date, cmo: cmo, currDay: this.isCurrDay(dayNbr, m, y, cmo, today), dayNbr: this.getDayNumber(date), disabled: this.utilService.isDisabledDay(date, this.opts.disableUntil, this.opts.disableSince, this.opts.disableWeekends, this.opts.disableDays, this.opts.disableDateRange, this.opts.enableDays)}); + dayNbr++; + } + } + let weekNbr: number = this.opts.showWeekNumbers && this.opts.firstDayOfWeek === "mo" ? this.utilService.getWeekNumber(week[0].dateObj) : 0; + this.dates.push({week: week, weekNbr: weekNbr}); + } + + this.setHeaderBtnDisabledState(m, y); + + if (notifyChange) { + // Notify parent + this.calendarViewChanged.emit({year: y, month: m, first: {number: 1, weekday: this.getWeekday({year: y, month: m, day: 1})}, last: {number: dInThisM, weekday: this.getWeekday({year: y, month: m, day: dInThisM})}}); + } + } + + parseSelectedDate(selDate: any): IMyDate { + // Parse selDate value - it can be string or IMyDate object + let date: IMyDate = {day: 0, month: 0, year: 0}; + if (typeof selDate === "string") { + let sd: string = selDate; + date.day = this.utilService.parseDatePartNumber(this.opts.dateFormat, sd, "dd"); + + date.month = this.opts.dateFormat.indexOf("mmm") !== -1 + ? this.utilService.parseDatePartMonthName(this.opts.dateFormat, sd, "mmm", this.opts.monthLabels) + : this.utilService.parseDatePartNumber(this.opts.dateFormat, sd, "mm"); + + date.year = this.utilService.parseDatePartNumber(this.opts.dateFormat, sd, "yyyy"); + } + else if (typeof selDate === "object") { + date = selDate; + } + this.selectionDayTxt = this.formatDate(date); + return date; + } + + parseSelectedMonth(ms: string): IMyMonth { + return this.utilService.parseDefaultMonth(ms); + } + + setHeaderBtnDisabledState(m: number, y: number): void { + let dpm: boolean = false; + let dpy: boolean = false; + let dnm: boolean = false; + let dny: boolean = false; + if (this.opts.disableHeaderButtons) { + dpm = this.utilService.isMonthDisabledByDisableUntil({year: m === 1 ? y - 1 : y, month: m === 1 ? 12 : m - 1, day: this.daysInMonth(m === 1 ? 12 : m - 1, m === 1 ? y - 1 : y)}, this.opts.disableUntil); + dpy = this.utilService.isMonthDisabledByDisableUntil({year: y - 1, month: m, day: this.daysInMonth(m, y - 1)}, this.opts.disableUntil); + dnm = this.utilService.isMonthDisabledByDisableSince({year: m === 12 ? y + 1 : y, month: m === 12 ? 1 : m + 1, day: 1}, this.opts.disableSince); + dny = this.utilService.isMonthDisabledByDisableSince({year: y + 1, month: m, day: 1}, this.opts.disableSince); + } + this.prevMonthDisabled = m === 1 && y === this.opts.minYear || dpm; + this.prevYearDisabled = y - 1 < this.opts.minYear || dpy; + this.nextMonthDisabled = m === 12 && y === this.opts.maxYear || dnm; + this.nextYearDisabled = y + 1 > this.opts.maxYear || dny; + } +} diff --git a/utils/my-date-picker/my-date-picker.module.ts b/utils/my-date-picker/my-date-picker.module.ts new file mode 100644 index 00000000..a638a905 --- /dev/null +++ b/utils/my-date-picker/my-date-picker.module.ts @@ -0,0 +1,14 @@ +import { CommonModule } from "@angular/common"; +import { FormsModule } from "@angular/forms"; +import { NgModule } from "@angular/core"; +import { MyDatePicker } from "./my-date-picker.component"; +import { FocusDirective } from "./directives/my-date-picker.focus.directive"; +import { InputAutoFillDirective } from "./directives/my-date-picker.input.auto.fill.directive"; + +@NgModule({ + imports: [CommonModule, FormsModule], + declarations: [MyDatePicker, FocusDirective, InputAutoFillDirective], + exports: [MyDatePicker, FocusDirective, InputAutoFillDirective] +}) +export class MyDatePickerModule { +} diff --git a/utils/my-date-picker/services/my-date-picker.locale.service.ts b/utils/my-date-picker/services/my-date-picker.locale.service.ts new file mode 100644 index 00000000..44c209e9 --- /dev/null +++ b/utils/my-date-picker/services/my-date-picker.locale.service.ts @@ -0,0 +1,232 @@ +import { Injectable } from "@angular/core"; +import { IMyLocales, IMyOptions } from "../interfaces/index"; + +@Injectable() +export class LocaleService { + private locales: IMyLocales = { + "en": { + dayLabels: {su: "Sun", mo: "Mon", tu: "Tue", we: "Wed", th: "Thu", fr: "Fri", sa: "Sat"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "May", 6: "Jun", 7: "Jul", 8: "Aug", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Dec" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "Today", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "he": { + dayLabels: {su: "רא", mo: "שנ", tu: "של", we: "רב", th: "חמ", fr: "שי", sa: "שב"}, + monthLabels: { 1: "ינו", 2: "פבר", 3: "מרץ", 4: "אפר", 5: "מאי", 6: "יונ", 7: "יול", 8: "אוג", 9: "ספט", 10: "אוק", 11: "נוב", 12: "דצמ" }, + dateFormat: "dd/mm/yyyy", + todayBtnTxt: "היום", + firstDayOfWeek: "su", + sunHighlight: false + }, + "ja": { + dayLabels: {su: "日", mo: "月", tu: "火", we: "水", th: "木", fr: "金", sa: "土"}, + monthLabels: {1: "1月", 2: "2月", 3: "3月", 4: "4月", 5: "5月", 6: "6月", 7: "7月", 8: "8月", 9: "9月", 10: "10月", 11: "11月", 12: "12月"}, + dateFormat: "yyyy.mm.dd", + todayBtnTxt: "今日", + sunHighlight: false + }, + "fr": { + dayLabels: {su: "Dim", mo: "Lun", tu: "Mar", we: "Mer", th: "Jeu", fr: "Ven", sa: "Sam"}, + monthLabels: {1: "Jan", 2: "Fév", 3: "Mar", 4: "Avr", 5: "Mai", 6: "Juin", 7: "Juil", 8: "Aoû", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Déc"}, + dateFormat: "dd/mm/yyyy", + todayBtnTxt: "Aujourd'hui", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "fi": { + dayLabels: {su: "Su", mo: "Ma", tu: "Ti", we: "Ke", th: "To", fr: "Pe", sa: "La"}, + monthLabels: {1: "Tam", 2: "Hel", 3: "Maa", 4: "Huh", 5: "Tou", 6: "Kes", 7: "Hei", 8: "Elo", 9: "Syy", 10: "Lok", 11: "Mar", 12: "Jou"}, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Tänään", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "es": { + dayLabels: {su: "Do", mo: "Lu", tu: "Ma", we: "Mi", th: "Ju", fr: "Vi", sa: "Sa"}, + monthLabels: {1: "Ene", 2: "Feb", 3: "Mar", 4: "Abr", 5: "May", 6: "Jun", 7: "Jul", 8: "Ago", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Dic"}, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Hoy", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "hu": { + dayLabels: {su: "Vas", mo: "Hét", tu: "Kedd", we: "Sze", th: "Csü", fr: "Pén", sa: "Szo"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Már", 4: "Ápr", 5: "Máj", 6: "Jún", 7: "Júl", 8: "Aug", 9: "Szep", 10: "Okt", 11: "Nov", 12: "Dec" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "Ma", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "sv": { + dayLabels: {su: "Sön", mo: "Mån", tu: "Tis", we: "Ons", th: "Tor", fr: "Fre", sa: "Lör"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Maj", 6: "Jun", 7: "Jul", 8: "Aug", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Dec" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "Idag", + firstDayOfWeek: "mo", + sunHighlight: false + }, + "nl": { + dayLabels: {su: "Zon", mo: "Maa", tu: "Din", we: "Woe", th: "Don", fr: "Vri", sa: "Zat"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Mei", 6: "Jun", 7: "Jul", 8: "Aug", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Dec" }, + dateFormat: "dd-mm-yyyy", + todayBtnTxt: "Vandaag", + firstDayOfWeek: "mo", + sunHighlight: false + }, + "ru": { + dayLabels: {su: "Вс", mo: "Пн", tu: "Вт", we: "Ср", th: "Чт", fr: "Пт", sa: "Сб"}, + monthLabels: { 1: "Янв", 2: "Фев", 3: "Март", 4: "Апр", 5: "Май", 6: "Июнь", 7: "Июль", 8: "Авг", 9: "Сент", 10: "Окт", 11: "Ноя", 12: "Дек" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Сегодня", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "uk": { + dayLabels: {su: "Нд", mo: "Пн", tu: "Вт", we: "Ср", th: "Чт", fr: "Пт", sa: "Сб"}, + monthLabels: { 1: "Січ", 2: "Лют", 3: "Бер", 4: "Кві", 5: "Тра", 6: "Чер", 7: "Лип", 8: "Сер", 9: "Вер", 10: "Жов", 11: "Лис", 12: "Гру" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Сьогодні", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "no": { + dayLabels: {su: "Søn", mo: "Man", tu: "Tir", we: "Ons", th: "Tor", fr: "Fre", sa: "Lør"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Mai", 6: "Jun", 7: "Jul", 8: "Aug", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Des" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "I dag", + firstDayOfWeek: "mo", + sunHighlight: false + }, + "tr": { + dayLabels: {su: "Paz", mo: "Pzt", tu: "Sal", we: "Çar", th: "Per", fr: "Cum", sa: "Cmt"}, + monthLabels: { 1: "Oca", 2: "Şub", 3: "Mar", 4: "Nis", 5: "May", 6: "Haz", 7: "Tem", 8: "Ağu", 9: "Eyl", 10: "Eki", 11: "Kas", 12: "Ara" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Bugün", + firstDayOfWeek: "mo", + sunHighlight: false + }, + "pt-br": { + dayLabels: {su: "Dom", mo: "Seg", tu: "Ter", we: "Qua", th: "Qui", fr: "Sex", sa: "Sab"}, + monthLabels: { 1: "Jan", 2: "Fev", 3: "Mar", 4: "Abr", 5: "Mai", 6: "Jun", 7: "Jul", 8: "Ago", 9: "Set", 10: "Out", 11: "Nov", 12: "Dez" }, + dateFormat: "dd/mm/yyyy", + todayBtnTxt: "Hoje", + firstDayOfWeek: "su", + sunHighlight: true + }, + "de": { + dayLabels: {su: "So", mo: "Mo", tu: "Di", we: "Mi", th: "Do", fr: "Fr", sa: "Sa"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mär", 4: "Apr", 5: "Mai", 6: "Jun", 7: "Jul", 8: "Aug", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Dez" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Heute", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "it": { + dayLabels: { su: "Dom", mo: "Lun", tu: "Mar", we: "Mer", th: "Gio", fr: "Ven", sa: "Sab" }, + monthLabels: { 1: "Gen", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Mag", 6: "Giu", 7: "Lug", 8: "Ago", 9: "Set", 10: "Ott", 11: "Nov", 12: "Dic" }, + dateFormat: "dd/mm/yyyy", + todayBtnTxt: "Oggi", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "it-ch": { + dayLabels: { su: "Dom", mo: "Lun", tu: "Mar", we: "Mer", th: "Gio", fr: "Ven", sa: "Sab" }, + monthLabels: { 1: "Gen", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Mag", 6: "Giu", 7: "Lug", 8: "Ago", 9: "Set", 10: "Ott", 11: "Nov", 12: "Dic" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Oggi", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "pl": { + dayLabels: { su: "Nie", mo: "Pon", tu: "Wto", we: "Śro", th: "Czw", fr: "Pią", sa: "Sob" }, + monthLabels: { 1: "Sty", 2: "Lut", 3: "Mar", 4: "Kwi", 5: "Maj", 6: "Cze", 7: "Lip", 8: "Sie", 9: "Wrz", 10: "Paź", 11: "Lis", 12: "Gru" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "Dzisiaj", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "my": { + dayLabels: {su: "တနင်္ဂနွေ", mo: "တနင်္လာ", tu: "အင်္ဂါ", we: "ဗုဒ္ဓဟူး", th: "ကြသပတေး", fr: "သောကြာ", sa: "စနေ"}, + monthLabels: { 1: "ဇန်နဝါရီ", 2: "ဖေဖော်ဝါရီ", 3: "မတ်", 4: "ဧပြီ", 5: "မေ", 6: "ဇွန်", 7: "ဇူလိုင်", 8: "ဩဂုတ်", 9: "စက်တင်ဘာ", 10: "အောက်တိုဘာ", 11: "နိုဝင်ဘာ", 12: "ဒီဇင်ဘာ" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "ယနေ့", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "sk": { + dayLabels: { su: "Ne", mo: "Po", tu: "Ut", we: "St", th: "Št", fr: "Pi", sa: "So" }, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Máj", 6: "Jún", 7: "Júl", 8: "Aug", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Dec" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Dnes", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "sl": { + dayLabels: { su: "Ned", mo: "Pon", tu: "Tor", we: "Sre", th: "Čet", fr: "Pet", sa: "Sob" }, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Maj", 6: "Jun", 7: "Jul", 8: "Avg", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Dec" }, + dateFormat: "dd. mm. yyyy", + todayBtnTxt: "Danes", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "zh-cn": { + dayLabels: {su: "日", mo: "一", tu: "二", we: "三", th: "四", fr: "五", sa: "六"}, + monthLabels: { 1: "1月", 2: "2月", 3: "3月", 4: "4月", 5: "5月", 6: "6月", 7: "7月", 8: "8月", 9: "9月", 10: "10月", 11: "11月", 12: "12月" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "今天", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "ro": { + dayLabels: {su: "du", mo: "lu", tu: "ma", we: "mi", th: "jo", fr: "vi", sa: "sa"}, + monthLabels: { 1: "ian", 2: "feb", 3: "mart", 4: "apr", 5: "mai", 6: "iun", 7: "iul", 8: "aug", 9: "sept", 10: "oct", 11: "nov", 12: "dec" }, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Astăzi", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "ca": { + dayLabels: {su: "dg", mo: "dl", tu: "dt", we: "dc", th: "dj", fr: "dv", sa: "ds"}, + monthLabels: {1: "Gen", 2: "Febr", 3: "Març", 4: "Abr", 5: "Maig", 6: "Juny", 7: "Jul", 8: "Ag", 9: "Set", 10: "Oct", 11: "Nov", 12: "Des"}, + dateFormat: "dd.mm.yyyy", + todayBtnTxt: "Avui", + firstDayOfWeek: "mo", + sunHighlight: true, + }, + "id": { + dayLabels: {su: "Min", mo: "Sen", tu: "Sel", we: "Rab", th: "Kam", fr: "Jum", sa: "Sab"}, + monthLabels: {1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "Mei", 6: "Jun", 7: "Jul", 8: "Ags", 9: "Sep", 10: "Okt", 11: "Nov", 12: "Des"}, + dateFormat: "dd-mm-yyyy", + todayBtnTxt: "Hari ini", + firstDayOfWeek: "su", + sunHighlight: true + }, + "en-au": { + dayLabels: {su: "Sun", mo: "Mon", tu: "Tue", we: "Wed", th: "Thu", fr: "Fri", sa: "Sat"}, + monthLabels: { 1: "Jan", 2: "Feb", 3: "Mar", 4: "Apr", 5: "May", 6: "Jun", 7: "Jul", 8: "Aug", 9: "Sep", 10: "Oct", 11: "Nov", 12: "Dec" }, + dateFormat: "dd/mm/yyyy", + todayBtnTxt: "Today", + firstDayOfWeek: "mo", + sunHighlight: true + }, + "am-et": { + dayLabels: {su: "እሑድ", mo: "ሰኞ", tu: "ማክሰኞ", we: "ረቡዕ", th: "ሐሙስ", fr: "ዓርብ", sa: "ቅዳሜ"}, + monthLabels: { 1: "ጃንዩ", 2: "ፌብሩ", 3: "ማርች", 4: "ኤፕረ", 5: "ሜይ", 6: "ጁን", 7: "ጁላይ", 8: "ኦገስ", 9: "ሴፕቴ", 10: "ኦክተ", 11: "ኖቬም", 12: "ዲሴም" }, + dateFormat: "yyyy-mm-dd", + todayBtnTxt: "ዛሬ", + firstDayOfWeek: "mo", + sunHighlight: true + } + }; + + getLocaleOptions(locale: string): IMyOptions { + if (locale && this.locales.hasOwnProperty(locale)) { + // User given locale + return this.locales[locale]; + } + // Default: en + return this.locales["en"]; + } +} diff --git a/utils/my-date-picker/services/my-date-picker.util.service.ts b/utils/my-date-picker/services/my-date-picker.util.service.ts new file mode 100644 index 00000000..98b51bca --- /dev/null +++ b/utils/my-date-picker/services/my-date-picker.util.service.ts @@ -0,0 +1,169 @@ +import { Injectable } from "@angular/core"; +import { IMyDate } from "../interfaces/my-date.interface"; +import { IMyDateRange } from "../interfaces/my-date-range.interface"; +import { IMyMonth } from "../interfaces/my-month.interface"; +import { IMyMonthLabels } from "../interfaces/my-month-labels.interface"; + +@Injectable() +export class UtilService { + isDateValid(dateStr: string, dateFormat: string, minYear: number, maxYear: number, disableUntil: IMyDate, disableSince: IMyDate, disableWeekends: boolean, disableDays: Array, disableDateRange: IMyDateRange, monthLabels: IMyMonthLabels, enableDays: Array): IMyDate { + let returnDate: IMyDate = {day: 0, month: 0, year: 0}; + let daysInMonth: Array = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + let isMonthStr: boolean = this.getDatePartIndex(dateFormat, "mmm") !== -1; + + if (dateStr.length !== dateFormat.length) { + return returnDate; + } + + let separator: string = this.getDateFormatSeparator(dateFormat); + + let parts: Array = dateStr.split(separator); + if (parts.length !== 3) { + return returnDate; + } + + let day: number = this.parseDatePartNumber(dateFormat, dateStr, "dd"); + let month: number = isMonthStr ? this.parseDatePartMonthName(dateFormat, dateStr, "mmm", monthLabels) : this.parseDatePartNumber(dateFormat, dateStr, "mm"); + let year: number = this.parseDatePartNumber(dateFormat, dateStr, "yyyy"); + + if (day !== -1 && month !== -1 && year !== -1) { + if (year < minYear || year > maxYear || month < 1 || month > 12) { + return returnDate; + } + + let date: IMyDate = {year: year, month: month, day: day}; + + if (this.isDisabledDay(date, disableUntil, disableSince, disableWeekends, disableDays, disableDateRange, enableDays)) { + return returnDate; + } + + if (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)) { + daysInMonth[1] = 29; + } + + if (day < 1 || day > daysInMonth[month - 1]) { + return returnDate; + } + + // Valid date + return date; + } + return returnDate; + } + + getDateFormatSeparator(dateFormat: string): string { + return dateFormat.replace(/[dmy]/g, "")[0]; + } + + isMonthLabelValid(monthLabel: string, monthLabels: IMyMonthLabels): number { + for (let key = 1; key <= 12; key++) { + if (monthLabel.toLowerCase() === monthLabels[key].toLowerCase()) { + return key; + } + } + return -1; + } + + isYearLabelValid(yearLabel: number, minYear: number, maxYear: number): number { + if (yearLabel >= minYear && yearLabel <= maxYear) { + return yearLabel; + } + return -1; + } + + parseDatePartNumber(dateFormat: string, dateString: string, datePart: string): number { + let pos: number = this.getDatePartIndex(dateFormat, datePart); + if (pos !== -1) { + let value: string = dateString.substring(pos, pos + datePart.length); + if (!/^\d+$/.test(value)) { + return -1; + } + return parseInt(value); + } + return -1; + } + + parseDatePartMonthName(dateFormat: string, dateString: string, datePart: string, monthLabels: IMyMonthLabels): number { + let pos: number = this.getDatePartIndex(dateFormat, datePart); + if (pos !== -1) { + return this.isMonthLabelValid(dateString.substring(pos, pos + datePart.length), monthLabels); + } + return -1; + } + + getDatePartIndex(dateFormat: string, datePart: string): number { + return dateFormat.indexOf(datePart); + } + + parseDefaultMonth(monthString: string): IMyMonth { + let month: IMyMonth = {monthTxt: "", monthNbr: 0, year: 0}; + if (monthString !== "") { + let split = monthString.split(monthString.match(/[^0-9]/)[0]); + month.monthNbr = split[0].length === 2 ? parseInt(split[0]) : parseInt(split[1]); + month.year = split[0].length === 2 ? parseInt(split[1]) : parseInt(split[0]); + } + return month; + } + + isDisabledDay(date: IMyDate, disableUntil: IMyDate, disableSince: IMyDate, disableWeekends: boolean, disableDays: Array, disableDateRange: IMyDateRange, enableDays: Array): boolean { + for (let obj of enableDays) { + if (obj.year === date.year && obj.month === date.month && obj.day === date.day) { + return false; + } + } + + let dateMs: number = this.getTimeInMilliseconds(date); + if (this.isInitializedDate(disableUntil) && dateMs <= this.getTimeInMilliseconds(disableUntil)) { + return true; + } + + if (this.isInitializedDate(disableSince) && dateMs >= this.getTimeInMilliseconds(disableSince)) { + return true; + } + + if (disableWeekends) { + let dayNbr = this.getDayNumber(date); + if (dayNbr === 0 || dayNbr === 6) { + return true; + } + } + + for (let obj of disableDays) { + if (obj.year === date.year && obj.month === date.month && obj.day === date.day) { + return true; + } + } + + if (this.isInitializedDate(disableDateRange.begin) && this.isInitializedDate(disableDateRange.end) && dateMs >= this.getTimeInMilliseconds(disableDateRange.begin) && dateMs <= this.getTimeInMilliseconds(disableDateRange.end)) { + return true; + } + return false; + } + + getWeekNumber(date: IMyDate): number { + let d: Date = new Date(date.year, date.month - 1, date.day, 0, 0, 0, 0); + d.setDate(d.getDate() + (d.getDay() === 0 ? -3 : 4 - d.getDay())); + return Math.round(((d.getTime() - new Date(d.getFullYear(), 0, 4).getTime()) / 86400000) / 7) + 1; + } + + isMonthDisabledByDisableUntil(date: IMyDate, disableUntil: IMyDate): boolean { + return this.isInitializedDate(disableUntil) && this.getTimeInMilliseconds(date) <= this.getTimeInMilliseconds(disableUntil); + } + + isMonthDisabledByDisableSince(date: IMyDate, disableSince: IMyDate): boolean { + return this.isInitializedDate(disableSince) && this.getTimeInMilliseconds(date) >= this.getTimeInMilliseconds(disableSince); + } + + isInitializedDate(date: IMyDate): boolean { + return date.year !== 0 && date.month !== 0 && date.day !== 0; + } + + getTimeInMilliseconds(date: IMyDate): number { + return new Date(date.year, date.month - 1, date.day, 0, 0, 0, 0).getTime(); + } + + getDayNumber(date: IMyDate): number { + let d: Date = new Date(date.year, date.month - 1, date.day, 0, 0, 0, 0); + return d.getDay(); + } +} \ No newline at end of file diff --git a/utils/number-utils.class.ts b/utils/number-utils.class.ts new file mode 100644 index 00000000..bc6e25ce --- /dev/null +++ b/utils/number-utils.class.ts @@ -0,0 +1,31 @@ + +export class NumberUtils{ + + + + public static roundNumber(num: number):any { + console.log("Trying to round number: "+ num); + var roundNum = null; + if(num >= 1000000){ + num=num/1000000; + num= Math.round(num); + roundNum = { "number": num, "size": "mi" }; + }else if( num >= 10000){ + num=num/1000; + num= Math.round(num); + roundNum = { "number": num, "size": "K" }; + }else if (num >= 100) { + num=num/100; + num= Math.round(num); + num=num*100; + roundNum = { "number": num, "size": "" }; + }else{ + roundNum = { "number": num, "size": "" }; + } + console.log("Rounded number: "+ roundNum.number + " "+ roundNum.size); + return roundNum; + } + + + +} diff --git a/utils/paging.module.ts b/utils/paging.module.ts new file mode 100644 index 00000000..dbf53c87 --- /dev/null +++ b/utils/paging.module.ts @@ -0,0 +1,28 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; + +import {pagingFormatterNoLoad} from './pagingFormatterNoLoad.component'; + +import {PagingFormatter} from './pagingFormatter.component'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule, RouterModule + ], + declarations: [ + pagingFormatterNoLoad, + PagingFormatter, + + + ], + exports: [ + pagingFormatterNoLoad, + PagingFormatter, + + + ] +}) +export class PagingModule { } diff --git a/utils/pagingFormatter.component.ts b/utils/pagingFormatter.component.ts new file mode 100644 index 00000000..f199aaa9 --- /dev/null +++ b/utils/pagingFormatter.component.ts @@ -0,0 +1,64 @@ +import {Component, Input} from '@angular/core'; +import {Router} from '@angular/router'; +import {DomSanitizer} from '@angular/platform-browser'; +//Usage Example +import {RouterHelper} from './routerHelper.class'; + +@Component({ + selector: 'paging', + template: ` + + + + ` +}) + +export class PagingFormatter { + @Input() currentPage: number = 1; + @Input() size: number=10; + @Input() totalResults: number = 10; + @Input() baseUrl:string=""; + @Input() parameterNames:string[]; + @Input() parameterValues:string[]; + + public routerHelper:RouterHelper = new RouterHelper(); + + constructor ( private _router: Router, private sanitizer:DomSanitizer) { + } + + ngOnInit() { + + } + getTotalPages(){ + var i:number =parseInt(''+(this.totalResults/this.size)); + return (((this.totalResults/this.size) == i )? i :(i+1)) ; + } + + // onPage(pageNum: number){ + // return this.sanitizer.bypassSecurityTrustUrl( this.baseUrl+((this.baseUrl.indexOf("?") > -1 )?'&':'?')+ "page=" + (pageNum)); + // + // } +} diff --git a/utils/pagingFormatterNoLoad.component.ts b/utils/pagingFormatterNoLoad.component.ts new file mode 100644 index 00000000..2ae49f49 --- /dev/null +++ b/utils/pagingFormatterNoLoad.component.ts @@ -0,0 +1,76 @@ +import {Component, Input, Output, EventEmitter} from '@angular/core'; + + +//Usage Example + +@Component({ + selector: 'paging-no-load', + template: ` + + + ` +}) + +export class pagingFormatterNoLoad { + @Input() public currentPage: number = 1; + // @Input() public navigateTo: string; + @Input() public term: string=''; + @Input() public size: number=10; + @Input() public totalResults: number = 10; + // @Input() public params; + + @Output() pageChange = new EventEmitter(); + + constructor () { + } + + ngOnInit() { + console.info("In paging -- CurrentPage:"+this.currentPage+" "+"total Pages = "+this.getTotalPages() +" Results num:"+this.totalResults); + } + getTotalPages(){ + var i= this.totalResults/this.size; + var integerI=parseInt(''+i); + return parseInt(''+((i==integerI)?i:i+1)); + } + onPrev(){ + this.currentPage=this.currentPage-1; + this.pageChange.emit({ + value: this.currentPage + }); + + } + + onNext(){ + + this.currentPage=this.currentPage+1; + this.pageChange.emit({ + value: this.currentPage + }); + } + onPage(pageNum: number){ + + this.currentPage=pageNum; + this.pageChange.emit({ + value: this.currentPage + }); + } +} diff --git a/utils/pipes/claimsDatatable.pipe.ts b/utils/pipes/claimsDatatable.pipe.ts new file mode 100644 index 00000000..d05ca549 --- /dev/null +++ b/utils/pipes/claimsDatatable.pipe.ts @@ -0,0 +1,48 @@ +import { Pipe, PipeTransform} from '@angular/core' + + +@Pipe({ + name: 'claimsDatatable' +}) +export class ClaimsDatatablePipe implements PipeTransform { + + transform(array: any[], args: any[]): any { + let query: string = args[0]; + let counter:any = args[1]; + let active: any = args[2]; + + active.page = 1; + + if (query) { + var result = array.filter(row=>this.filterAll(row, query)); + counter.count = result.length; + return result; + } + return array; + } + + filterAll(row: any, query: string) { + if(row.userMail.indexOf(query) > -1) { + return true; + } + if(row.targetType != 'project' && row.target.title.indexOf(query) > -1) { + return true; + } + if(row.sourceType != 'project' && row.source.title.indexOf(query) > -1) { + return true; + } + if(row.date.indexOf(query) > -1) { + return true; + } + + if(row.curatedBy != null && row.curatedBy.indexOf(query) > -1) { + return true; + } + + if(row.curationDate != null && row.curationDate.indexOf(query) > -1) { + return true; + } + + return false; + } +} diff --git a/utils/pipes/contentProvidersDatatable.pipe.ts b/utils/pipes/contentProvidersDatatable.pipe.ts new file mode 100644 index 00000000..2484e7aa --- /dev/null +++ b/utils/pipes/contentProvidersDatatable.pipe.ts @@ -0,0 +1,113 @@ +import { Pipe, PipeTransform} from '@angular/core'; +import { Filter, Value} from '../../searchPages/searchUtils/searchHelperClasses.class'; +import { SearchUtilsClass } from '../../searchPages/searchUtils/searchUtils.class'; +import { ErrorCodes} from '../properties/openaireProperties'; + +@Pipe({ + name: 'contentProvidersDatatable' +}) +export class ContentProvidersDatatablePipe implements PipeTransform { + + transform(array: any[], args: any[]): any { + if(array.length > 0) { + let searchUtils: SearchUtilsClass = args[0]; + let filters:Filter[] = args[1]; + + + var errorCodes:ErrorCodes = new ErrorCodes(); + searchUtils.status = errorCodes.LOADING; + + var result = array.filter(row=>this.filterAll(row, searchUtils.keyword.toLowerCase(), filters)); + + let oldTotal = searchUtils.totalResults; + + searchUtils.totalResults = result.length; + + var errorCodes:ErrorCodes = new ErrorCodes(); + searchUtils.status = errorCodes.DONE; + if(searchUtils.totalResults == 0 ){ + searchUtils.status = errorCodes.NONE; + } + + if(oldTotal != searchUtils.totalResults) { + args[3].detectChanges(); + } + return result; + } + return []; + } + + filterAll(row: any, query: string, filters:Filter[]) { + let returnValue: boolean = false; + + if(query) { + if(row.title.name.toLowerCase().indexOf(query) > -1) { + returnValue = true; + } + + if(row.type.toLowerCase().indexOf(query) > -1) { + returnValue = true; + } + + if(row.countries && row.countries.length > 0) { + for(let country of row.countries) { + if(country.toLowerCase().indexOf(query) > -1) { + returnValue = true; + break; + } + } + } + + if(row.compatibility && row.compatibility.toLowerCase().indexOf(query) > -1) { + returnValue = true; + } + + if(row.organizations && row.organizations.length > 0) { + for(let organization of row.organizations) { + if(organization.name.toLowerCase().indexOf(query) > -1) { + returnValue = true; + break; + } + } + } + + if(!returnValue) { + return false; + } + } + + for (let filter of filters){ + if(filter.countSelectedValues > 0){ + for (let value of filter.values){ + if(value.selected == true){ + + // make it generic in future commit + let field:string = ""; + if(filter.title == "Type") { + field = "type"; + } else if(filter.title == "Compatibility Level") { + field = "compatibility"; + } + + if(row[field] == value.name) { + returnValue = true; + if(filter.filterOperator == "or") { + break; + } + } else { + if(filter.filterOperator == "and") { + return false; + } + returnValue = false; + } + } + } + if(!returnValue) { + return false; + } + } + } + + return true; + } +} diff --git a/utils/pipes/safeHTML.pipe.ts b/utils/pipes/safeHTML.pipe.ts new file mode 100644 index 00000000..1f0c5497 --- /dev/null +++ b/utils/pipes/safeHTML.pipe.ts @@ -0,0 +1,12 @@ +//our root app component +import { Pipe, PipeTransform} from '@angular/core' + +import { DomSanitizer, SafeUrl } from '@angular/platform-browser' + +@Pipe({ name: 'safeHtml'}) +export class SafeHtmlPipe implements PipeTransform { + constructor(private sanitized: DomSanitizer) {} + transform(value):SafeUrl { + return this.sanitized.bypassSecurityTrustHtml(value); + } +} diff --git a/utils/piwik/piwik.service.ts b/utils/piwik/piwik.service.ts new file mode 100644 index 00000000..c3c17746 --- /dev/null +++ b/utils/piwik/piwik.service.ts @@ -0,0 +1,70 @@ +import {Injectable} from '@angular/core'; +import {Http, Response, Headers, RequestOptions, URLSearchParams} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; +import {Location} from '@angular/common'; + +import {OpenaireProperties} from '../properties/openaireProperties'; +import {StringUtils} from '../string-utils.class'; + + +@Injectable() +export class PiwikService { + private piwikbaseUrl:string = ""; + constructor(private http: Http, private location: Location ) {} + + trackView (title):any { + + var ua = this.getUserAgent(); + var referrer = this.getReferrer(); + if(typeof location !== 'undefined'){ + var url = OpenaireProperties.getPiwikBaseURL()+"&rec=1&url="+StringUtils.URIEncode(location.href)+"&action_name="+StringUtils.URIEncode(title)+ + ((ua != null && ua.length > 0)?('&ua='+StringUtils.URIEncode(ua)):'')+ + ((referrer != null && referrer.length > 0)?('&urlref='+StringUtils.URIEncode(referrer)):''); + console.log("Piwik - View: " + url); + + return this.http.get( url); + // .do(request => console.info("Piwik request completed" )); + + } + } + trackDownload (downloadURL):any { + var ua = this.getUserAgent(); + var referrer = this.getReferrer(); + var url = OpenaireProperties.getPiwikBaseURL()+"&rec=1&url="+StringUtils.URIEncode(downloadURL)+"&download="+StringUtils.URIEncode(downloadURL)+ + ((ua != null && ua.length > 0)?('&ua='+StringUtils.URIEncode(ua)):'')+ + ((referrer != null && referrer.length > 0)?('&urlref='+StringUtils.URIEncode(referrer)):''); + console.log("Piwik - trackDownload: "+url); + + return this.http.get( url) + .do(request => console.info("Piwik request completed" )); + + } + private getUserAgent(){ + if (typeof navigator !== 'undefined') { + console.log("navigator.userAgent:" + navigator.userAgent); + return navigator.userAgent; + + }else{ + return null; + } + } + private getReferrer(){ + var referrer = ""; + if (typeof document !== 'undefined') { + console.log("document.referrer:" + document.referrer); + referrer = document.referrer; + + } + if((referrer == null || referrer.length == 0)&&typeof localStorage !== 'undefined'){ + + referrer =localStorage.getItem('previousRoute'); + } + return referrer; + } + parse(data:any){ + } + +} diff --git a/utils/piwik/piwikService.module.ts b/utils/piwik/piwikService.module.ts new file mode 100644 index 00000000..0cfe47e3 --- /dev/null +++ b/utils/piwik/piwikService.module.ts @@ -0,0 +1,21 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {PiwikService} from './piwik.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule, + + ], + declarations: [ + + ], + providers: [ PiwikService ], + exports: [ + + ] +}) +export class PiwikServiceModule{ } diff --git a/utils/piwik/previousRouteRecorder.guard.ts b/utils/piwik/previousRouteRecorder.guard.ts new file mode 100644 index 00000000..ae62b524 --- /dev/null +++ b/utils/piwik/previousRouteRecorder.guard.ts @@ -0,0 +1,17 @@ + +import { Injectable } from '@angular/core'; +import { CanDeactivate, Router} from '@angular/router'; +import {Observable} from 'rxjs/Observable'; + +@Injectable() // do not forget to register this class as a provider +export class PreviousRouteRecorder implements CanDeactivate { + constructor(private router: Router) { + } + canDeactivate(component: any): Observable | boolean { + if (typeof localStorage !== 'undefined') { + console.log("In PreviousRouteRecorder : "+this.router.url ); + localStorage.setItem('previousRoute', this.router.url); + } + return true; + } +} diff --git a/utils/properties/openaireProperties.ts b/utils/properties/openaireProperties.ts new file mode 100644 index 00000000..412fe887 --- /dev/null +++ b/utils/properties/openaireProperties.ts @@ -0,0 +1,417 @@ +export class OpenaireProperties { + private static productionMode:boolean = false; + private static enablePiwikTrack:boolean = false; + private static enableHelper:boolean = false; + private static useCache:boolean = true; + + //base url + private static baseLink = "https://demo.openaire.eu"; + + //landing Pages + private static baseSearchLink="/"; + private static searchLinkToPublication = "search/publication?articleId="; + private static searchLinkToProject = "search/project?projectId="; + private static searchLinkToDataProvider = "search/dataprovider?datasourceId="; + private static searchLinkToDataset = "search/dataset?datasetId="; + private static searchLinkToOrganization = "search/organization?organizationId="; + //Search pages + private static searchLinkToPublications = "search/find/publications"; + private static searchLinkToDataProviders = "search/find/dataproviders"; + private static searchLinkToProjects = "search/find/projects"; + private static searchLinkToDatasets = "search/find/datasets"; + private static searchLinkToSoftware = "search/find/software"; + private static searchLinkToOrganizations = "search/find/organizations"; + private static searchLinkToPeople = "search/find/people"; + public static searchLinkToCompatibleDataProviders = "search/content-providers"; + public static searchLinkToCompatibleDataProvidersTable = "search/content-providers-table"; + public static searchLinkToEntityRegistriesDataProviders = "search/entity-registries"; + public static searchLinkToEntityRegistriesDataProvidersTable = "search/entity-registries-table"; + public static searchLinkToJournals = "search/journals"; + public static searchLinkToJournalsTable = "search/journals-table"; + + //Advanced Search for pages + public static searchLinkToAdvancedPublications = "search/advanced/publications"; + public static searchLinkToAdvancedProjects = "search/advanced/projects"; + public static searchLinkToAdvancedDatasets = "search/advanced/datasets"; + public static searchLinkToAdvancedSoftware = "search/advanced/software"; + public static searchLinkToAdvancedDataProviders = "search/advanced/dataproviders"; + public static searchLinkToAdvancedOrganizations = "search/advanced/organizations"; + public static searchLinkToAdvancedPeople = "search/advanced/people"; + + + private static metricsAPIURL = "https://beta.services.openaire.eu/usagestats/"; + private static framesAPIURL = "https://beta.openaire.eu/stats3/"; + + private static loginAPIURL = "http://rudie.di.uoa.gr:8080/dnet%2Dopenaire%2Dusers%2D1.0.0%2DSNAPSHOT/api/users/authenticates" + //"http://scoobydoo.di.uoa.gr:8080/uoa-user-management-1.0.0-SNAPSHOT/api/users/authenticates"; + private static loginAPIURL_pm = "https://beta.services.openaire.eu/uoa-user-management/api/users/authenticates"; + + private static claimsAPIURL = "http://scoobydoo.di.uoa.gr:8080/dnet-claims-service-2.0.0-SNAPSHOT/rest/claimsService/"; + private static claimsAPIURL_pm = "https://beta.services.openaire.eu/claims/rest/claimsService/"; + + private static searchAPIURLLAst_pm = "https://beta.services.openaire.eu/search/v2/api/"; + private static searchAPIURLLAst = "https://beta.services.openaire.eu/search/v2/api/"; +// private static searchAPIURLLAst = "http://scoobydoo.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2/api/"; + + private static searchResourcesAPIURL_pm = "https://beta.services.openaire.eu/search/v2/api/resources"; + private static searchResourcesAPIURL = "https://beta.services.openaire.eu/search/v2/api/resources"; + // private static searchResourcesAPIURL = "http://scoobydoo.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2/api/resources"; + + + private static csvAPIURL_pm = "https://beta.services.openaire.eu/search/v2/api/";//publications?format=csv + // private static csvAPIURL = "http://rudie.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2/api/";//publications?format=csv + + private static csvAPIURL = "https://beta.services.openaire.eu/search/v2/api/";//publications?format=csv + + private static searchCrossrefAPIURL = "https://api.crossref.org/works"; + // private static searchDataciteAPIURL = "https://search.datacite.org/api"; + private static searchDataciteAPIURL = "https://api.datacite.org/works"; + + private static searchOrcidURL = "https://pub.orcid.org/"; + + // Identifiers + private static pmidURL = "http://www.ncbi.nlm.nih.gov/pubmed/"; + private static doiURL = "https://dx.doi.org/"; + private static cordisURL = "http://cordis.europa.eu/projects/"; + private static pmcURL = "http://europepmc.org/articles/"; + private static handleURL = "http://hdl.handle.net/"; + + // Zenodo's url + private static zenodo = "https://zenodo.org/"; + // Open access link + private static openAccess = "https://www.openaire.eu/support/faq#article-id-234"; + // Open access repository link + private static openAccessRepo = "https://www.openaire.eu/support/faq#article-id-310"; + // FP7 link + private static fp7Guidlines = "https://www.openaire.eu/open-access-in-fp7-seventh-research-framework-programme"; + // H2020 link + private static h2020Guidlines = "https://www.openaire.eu/oa-publications/h2020/open-access-in-horizon-2020"; + // ERC Guidlines + private static ercGuidlines = "http://erc.europa.eu/sites/default/files/document/file/ERC_Open_Access_Guidelines-revised_2014.pdf"; + // helpdesk link + private static helpdesk = "https://www.openaire.eu/support/helpdesk"; + + private static uploadService_pm = "https://demo.openaire.eu/upload"; + private static uploadService = "http://scoobydoo.di.uoa.gr:8000/upload"; + + private static vocabulariesAPI ="https://beta.services.openaire.eu/provision/mvc/vocabularies/"; + + private static piwikBaseUrl =" https://analytics.openaire.eu/piwik.php?idsite=6"; + + + private static loginUrl ="http://mpagasas.di.uoa.gr:8080/dnet-openaire-users-1.0.0-SNAPSHOT/openid_connect_login"; + private static loginUrl_pm ="https://beta.services.openaire.eu/uoa-user-management/openid_connect_login"; + + private static logoutUrl ="https://aai.openminted.eu/proxy/saml2/idp/SingleLogoutService.php?ReturnTo="; + private static logoutUrl_pm ="https://aai.openminted.eu/proxy/saml2/idp/SingleLogoutService.php?ReturnTo="; + + private static logoutOpenaireUrl ="http://dl067.madgik.di.uoa.gr/idp/profile/Logout"; + private static logoutOpenaireUrl_pm ="http://dl067.madgik.di.uoa.gr/idp/profile/Logout"; + + + + private static cookieDomain =".di.uoa.gr"; + private static cookieDomain_pm =".openaire.eu"; + + private static feedbackmail ="openaire.test@gmail.com"; + + private static helperPageUrl ="http://scoobydoo.di.uoa.gr:16000/api/page/route"; + + private static cache ="http://scoobydoo.di.uoa.gr:3000/get?url="; + private static cache_pm ="https://demo.openaire.eu/cache/get?url="; + + + + public static getBaseLink():string{ + return this.baseLink; + } + + //landing Pages' getters + public static getsearchLinkToPublication():string{ + return this.baseSearchLink + this.searchLinkToPublication; + } + public static getsearchLinkToDataset():string{ + return this.baseSearchLink + this.searchLinkToDataset; + } + public static getsearchLinkToProject():string{ + return this.baseSearchLink + this.searchLinkToProject; + } + + public static getsearchLinkToOrganization():string{ + return this.searchLinkToOrganization; + } + public static getsearchLinkToDataProvider():string{ + return this.searchLinkToDataProvider; + } + //searchPages + public static getLinkToSearchPublications():string{ + return this.baseSearchLink + this.searchLinkToPublications; + } + public static getLinkToSearchProjects():string{ + return this.baseSearchLink + this.searchLinkToProjects; + } + public static getLinkToSearchDataProviders():string{ + return this.baseSearchLink + this.searchLinkToDataProviders; + } + public static getLinkToSearchCompatibleDataProviders():string{ + return this.baseSearchLink + this.searchLinkToCompatibleDataProviders; + } + public static getLinkToSearchCompatibleDataProvidersTable():string{ + return this.baseSearchLink + this.searchLinkToCompatibleDataProvidersTable; + } + public static getLinkToSearchEntityRegistries():string{ + return this.baseSearchLink + this.searchLinkToEntityRegistriesDataProviders; + } + public static getLinkToSearchEntityRegistriesTable():string{ + return this.baseSearchLink + this.searchLinkToEntityRegistriesDataProvidersTable; + } + public static getLinkToSearchJournals():string{ + return this.baseSearchLink + this.searchLinkToJournals; + } + public static getLinkToSearchJournalsTable():string{ + return this.baseSearchLink + this.searchLinkToJournalsTable; + } + public static getLinkToSearchDatasets():string{ + return this.baseSearchLink + this.searchLinkToDatasets; + } + public static getLinkToSearchSoftware():string{ + return this.baseSearchLink + this.searchLinkToSoftware; + } + public static getLinkToSearchOrganizations():string{ + return this.baseSearchLink + this.searchLinkToOrganizations; + } + public static getLinkToSearchPeople():string{ + return this.baseSearchLink + this.searchLinkToPeople; + } + + //Advanced searchPages + public static getLinkToAdvancedSearchPublications():string{ + return this.baseSearchLink + this.searchLinkToAdvancedPublications; + } + public static getLinkToAdvancedSearchProjects():string{ + return this.baseSearchLink + this.searchLinkToAdvancedProjects; + } + public static getLinkToAdvancedSearchDataProviders():string{ + return this.baseSearchLink + this.searchLinkToAdvancedDataProviders; + } + public static getLinkToAdvancedSearchDatasets():string{ + return this.baseSearchLink + this.searchLinkToAdvancedDatasets; + } + public static getLinkToAdvancedSearchSoftware():string{ + return this.baseSearchLink + this.searchLinkToAdvancedSoftware; + } + public static getLinkToAdvancedSearchOrganizations():string{ + return this.baseSearchLink + this.searchLinkToAdvancedOrganizations; + } + public static getLinkToAdvancedSearchPeople():string{ + return this.baseSearchLink + this.searchLinkToAdvancedPeople; + } + + // Services - APIs' getters + // public static getSearchAPIURL():string{ + // return this.searchAPIURL; + // } + // Services - APIs' getters + public static getCsvAPIURL(): string { + if(this.productionMode){ + return this.csvAPIURL_pm; + }else{ + return this.csvAPIURL; + } + // return this.csvAPIURL; + } + + public static getFramesAPIURL(): string { + return this.framesAPIURL; + } + + public static getMetricsAPIURL(): string { + return this.metricsAPIURL; + } + + public static getLoginAPIURL(): string { + if(this.productionMode){ + return this.loginAPIURL_pm; + }else{ + return this.loginAPIURL; + } + // return this.loginAPIURL; + } + + public static getSearchAPIURLLast():string{ + if(this.productionMode){ + return this.searchAPIURLLAst_pm; + }else{ + return this.searchAPIURLLAst; + } + // return this.searchAPIURLLAst; + } + //query using full query: + // + public static getSearchResourcesAPIURL():string{ + if(this.productionMode){ + return this.searchResourcesAPIURL_pm; + }else{ + return this.searchResourcesAPIURL; + } + // return this.searchResourcesAPIURL; + } + 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 == "software"){ + suffix="software/"; + }else if(entityType == "organization"){ + suffix="organizations/"; + }else if(entityType == "dataprovider"){ + suffix="datasources/"; + }else if(entityType == "person"){ + suffix="people/"; + } + return (this.productionMode?this.searchAPIURLLAst_pm:this.searchAPIURLLAst) + suffix; + } + + public static getClaimsAPIURL():string{ + if(this.productionMode){ + return this.claimsAPIURL_pm; + }else{ + return this.claimsAPIURL; + } + } + public static getSearchCrossrefAPIURL():string{ + return this.searchCrossrefAPIURL; + } + public static getSearchDataciteAPIURL():string{ + return this.searchDataciteAPIURL; + } + public static getSearchOrcidURL():string{ + return this.searchOrcidURL; + } + + // Identifiers' getters + public static getPmidURL():string{ + return this.pmidURL; + } + public static getDoiURL():string{ + return this.doiURL; + } + public static getCordisURL():string{ + return this.cordisURL; + } + public static getPmcURL():string{ + return this.pmcURL; + } + public static getHandleURL():string{ + return this.handleURL; + } + + // Zenodo's getter + public static getZenodoURL():string{ + return this.zenodo; + } + // Open access getter + public static getOpenAccess():string{ + return this.openAccess; + } + // Open access repository getter + public static getOpenAccessRepo():string{ + return this.openAccessRepo; + } + // FP7 link getter + public static getFP7Guidlines():string{ + return this.fp7Guidlines; + } + // H2020 link getter + public static getH2020Guidlines():string{ + return this.h2020Guidlines; + } + // ERC Guidlines getter + public static getERCGuidlines():string{ + return this.ercGuidlines; + } + // helpdesk link getter + public static getHelpdesk():string{ + return this.helpdesk; + } + + + //upload service for bulk claim - upload csv file + public static getUploadServiceUrl():string{ + if(this.productionMode){ + return this.uploadService_pm; + }else{ + return this.uploadService; + } + } + //vocabularies API + public static getVocabulariesAPI():string{ + return this.vocabulariesAPI; + } + public static getPiwikBaseURL():string{ + return this.piwikBaseUrl; + } + public static isPiwikTrackEnabled():boolean{ + return this.enablePiwikTrack; + } + public static getLoginURL():string{ + if(this.productionMode){ + return this.loginUrl_pm; + }else{ + return this.loginUrl; + } + } + public static getLogoutURL():string{ + if(this.productionMode){ + return this.logoutUrl_pm; + }else{ + return this.logoutUrl; + } + } + public static getLogoutOpenaireURL():string{ + if(this.productionMode){ + return this.logoutOpenaireUrl_pm; + }else{ + return this.logoutOpenaireUrl; + } + } + public static getCookieDomain():string{ + if(this.productionMode){ + return this.cookieDomain_pm; + }else{ + return this.cookieDomain; + } + } + public static getFeedbackMail():string{ + return this.feedbackmail; + } + public static getHelperPageUrl():string{ + return this.helperPageUrl; + } + public static isHelperEnabled():boolean{ + return this.enableHelper; + } + public static getCacheUrl():string{ + if(this.productionMode){ + return this.cache_pm; + }else{ + return this.cache; + } + } + public static isCacheEnabled():boolean{ + return this.useCache; + } +} +export class ErrorCodes { + public LOADING = 0; + public DONE = 1; + public NONE = 2; + public ERROR = 3; + public NOT_AVAILABLE = 4; + public OUT_OF_BOUND = 5; + public NOT_FOUND = 6; +} diff --git a/utils/properties/searchFields.ts b/utils/properties/searchFields.ts new file mode 100644 index 00000000..a38fc940 --- /dev/null +++ b/utils/properties/searchFields.ts @@ -0,0 +1,159 @@ +export class SearchFields { + //main Entities + //RESULTS + //Used for datasets and publications + //In case Datasets should display different fields, use seperate tables for fields + public RESULT_REFINE_FIELDS = [ + "relfunder", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id", + "relproject","resultacceptanceyear", + "resultbestaccessright", "instancetypename", "resultlanguagename", "community","resulthostingdatasource"]; + + public RESULT_ADVANCED_FIELDS:string[] = ["q","resulttitle","resultauthor","resultpublisher","instancetypename", + "resultlanguagename", "community","relprojectid", "relfunder", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id", + "resultdateofacceptance","resultbestaccessright","pid","resulthostingdatasourceid","collectedfromdatasourceid", "relorganizationid"]; + public RESULT_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["resulttitle"]:{name:"Title", type:"keyword", param:"title", equalityOperator: "="}, + ["resultauthor"]:{name:"Author", type:"keyword", param:"author", equalityOperator: "="}, + ["resultpublisher"]:{name:"Publisher", type:"keyword", param:"publisher", equalityOperator: "="}, + ["pid"]:{name:"PID", type:"keyword", param:"pid", equalityOperator: " = "}, + ["resulthostingdatasourceid"]:{name:"Hosting Content Provider", type:"entity", param:"hostedBy", equalityOperator: " exact "}, + ["resulthostingdatasource"]:{name:"Content Provider", type:"refine", param:"hostedBy", equalityOperator: " exact "}, + ["instancetypename"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + // ["instancetypenameid"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + ["resultlanguagename"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + // ["resultlanguageid"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + ["community"]:{name:"Community", type:"refine", param:"community", equalityOperator: " exact "}, + ["relproject"]:{name:"Project", type:"refine", param:"project", equalityOperator: " exact "}, + ["relprojectid"]:{name:"Project", type:"entity", param:"project", equalityOperator: " exact "}, + ["relfunder"]:{name:"Funder", type:"refine", param:"funder", equalityOperator: " exact "}, + ["relfundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", equalityOperator: " exact "}, + ["relfundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", equalityOperator: " exact "}, + ["relfundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", equalityOperator: " exact "}, + ["resultacceptanceyear"]:{name:"Publication Date", type:"keyword", param:"year", equalityOperator: " exact "}, + ["resultdateofacceptance"]:{name:"Publication Date", type:"date", param:"date", equalityOperator: " within "}, + ["resultbestaccessright"]:{name:"Access Mode", type:"vocabulary", param:"access", equalityOperator: " exact "}, + // ["resultbestaccessright"]:{name:"Access Mode", type:"refine", param:"access", equalityOperator: " exact "}, + ["collectedfrom"]:{name:"Content Provider", type:"refine", param:"datasource", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + }; + + //PROJECT + + public PROJECT_REFINE_FIELDS:string[] = ["funder","fundinglevel0_id","fundinglevel1_id", + "fundinglevel2_id","projectstartyear","projectendyear","projectecsc39"]; + public PROJECT_ADVANCED_FIELDS:string[] = ["q","projectacronym","projecttitle","projectkeywords", + "funder", "fundinglevel0_id","fundinglevel1_id", "fundinglevel2_id", + "projectstartdate","projectenddate","projectecsc39", + "projectcode_nt","relorganizationid", "collectedfromdatasourceid"]; + public PROJECT_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["projectacronym"]:{name:"Acronym", type:"keyword", param:"acronym", equalityOperator: "="}, + ["projecttitle"]:{name:"Title", type:"keyword", param:"title", equalityOperator: "="}, + ["projectkeywords"]:{name:"Keywords", type:"keyword", param:"keywords", equalityOperator: "="}, + + ["funder"]:{name:"Funder", type:"refine", param:"funder", equalityOperator: " exact "}, + ["fundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", equalityOperator: " exact "}, + ["fundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", equalityOperator: " exact "}, + ["fundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", equalityOperator: " exact "}, + ["projectstartyear"]:{name:"Start Year", type:"year", param:"startyear", equalityOperator: " exact "}, + ["projectendyear"]:{name:"End Year", type:"year", param:"endyear", equalityOperator: " exact "}, + ["projectstartdate"]:{name:"Start Date", type:"date", param:"startdate", equalityOperator: " within "}, + ["projectenddate"]:{name:"End Date", type:"date", param:"enddate", equalityOperator: " within "}, + ["projectecsc39"]:{name:"Special Clause 39", type:"boolean", param:"sc39", equalityOperator: " exact "}, + ["projectcode_nt"]:{name:"Project Code", type:"keyword", param:"code", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + + }; + + //DATAPROVIDERS + + public DATASOURCE_REFINE_FIELDS:string[] = ["datasourcetypeuiname", "datasourceodlanguages", "datasourceodcontenttypes", + "datasourcecompatibilityname"]; + public DATASOURCE_ADVANCED_FIELDS:string[] = ["q", "datasourceofficialname", + "datasourceenglishname","datasourceodsubjects", "datasourcetypename","datasourceodlanguages", + "datasourceodcontenttypes", "datasourcecompatibilityname","relorganizationid", "collectedfromdatasourceid"]; + + public DATASOURCE_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["datasourceofficialname"]:{name:"English name", type:"keyword", param:"officialname", equalityOperator: "="}, + ["datasourceenglishname"]:{name:"Title", type:"keyword", param:"engname", equalityOperator: "="}, + ["datasourceodsubjects"]:{name:"Subject", type:"keyword", param:"subjects", equalityOperator: "="}, + ["datasourcetypeuiid"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["datasourcetypeuiname"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["datasourcetypename"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + ["datasourceodlanguages"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + ["datasourceodcontenttypes"]:{name:"Content", type:"refine", param:"content", equalityOperator: " exact "}, + ["datasourcecompatibilityid"]:{name:"Compatibility Level", type:"refine", param:"compatibility", equalityOperator: " exact "}, + ["datasourcecompatibilityname"]:{name:"Compatibility Level", type:"vocabulary", param:"compatibility", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + }; + + public COMPATIBLE_DATAPROVIDER_FIELDS:string[] = ["datasourcetypeuiid","datasourcecompatibilityname"]; + public ENTITY_REGISTRIES_FIELDS:string[] = ["datasourcetypename","datasourcecompatibilityname"]; + public JOURNAL_FIELDS:string[] = ["datasourcetypeuiid","datasourcecompatibilityname"]; + + //ORGANIZATION + + public ORGANIZATION_REFINE_FIELDS:string[] = ["organizationcountryname"] + public ORGANIZATION_ADVANCED_FIELDS:string[] = ["q", "organizationlegalname","organizationlegalshortname","organizationcountryname"]; + + public ORGANIZATION_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["organizationlegalname"]:{name:"Legal Name", type:"keyword", param:"name", equalityOperator: "="}, + ["organizationlegalshortname"]:{name:"Legal Short Name", type:"keyword", param:"shortname", equalityOperator: "="}, + ["organizationcountryname"]:{name:"Country", type:"vocabulary", param:"country", equalityOperator: "="}, + // ["organizationcountryname"]:{name:"Country", type:"refine", param:"country", equalityOperator: "="} + }; + public ORGANIZATION_INDEX:string[] = ["organizationcountryname"]//,"organizationeclegalbody"]; + public ADVANCED_SEARCH_ORGANIZATION_PARAM:string[] = ["q","contenttype","compatibility","country","type"]; + public ORGANIZATION_INDEX_PARAM_MAP:{ [key:string]:string } = {["organizationlegalname"]:"contenttype", ["organizationlegalshortname"]:"type", + ["organizationcountryname"]:"country"};//,["organizationeclegalbody"]:"type"}; + public ORGANIZATION_FIELDS_MAP: { [key:string]:{ name:string, operator:string, type:string, indexField:string , equalityOperator:string}} ={ + ["q"]:{name:"All fields",operator:"op", type:"keyword", indexField:null, equalityOperator: "="}, + ["contenttype"]:{name:"Legal Name",operator:"cn", type:"keyword" , indexField:"organizationlegalname", equalityOperator: "="}, + ["compatibility"]:{name:"Legal Short Name",operator:"cm", type:"keyword", indexField:"organizationlegalshortname", equalityOperator: "="}, + ["country"]:{name:"Country",operator:"cu", type:"vocabulary", indexField:"organizationcountryname", equalityOperator: " exact "}, + ["type"]:{name:"Type",operator:"tp", type:"refine", indexField:"organizationeclegalbody", equalityOperator: " exact "}, + + }; + + + + public HIDDEN_FIELDS:string[] = ["fundinglevel0_id","fundinglevel1_id","fundinglevel2_id", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id"]; + + public DEPENDENT_FIELDS: { [key:string]:string } = {["fundinglevel0_id"]:"funder", + ["fundinglevel1_id"]:"fundinglevel0_id", ["fundinglevel2_id"]:"fundinglevel1_id", ["relfundinglevel0_id"]:"relfunder", + ["relfundinglevel1_id"]:"relfundinglevel0_id", ["relfundinglevel2_id"]:"relfundinglevel1_id"}; + + + public ADVANCED_SEARCH_OPERATORS:[{name:string, id:string}] = [{name:"AND",id:"and"},{name:"OR",id:"or"},{name:"NOT",id:"not"}]; + + constructor (){ + } + getFieldName(fieldId:string,fieldType:string):string{ + if(fieldType == "publication" || fieldType == "dataset" || fieldType == "software"){ + return this.RESULT_FIELDS[fieldId].name; + }else if(fieldType == "project"){ + return this.PROJECT_FIELDS[fieldId].name; + }else if(fieldType == "organization"){ + return this.ORGANIZATION_FIELDS[fieldId].name; + }else if(fieldType == "datasource" || fieldType == "dataprovider"){ + return this.DATASOURCE_FIELDS[fieldId].name; + }else{ + return "UNDEFINED"; + } + } +} +export class FieldDetails{ + name:string; + type:string; + param:string; + equalityOperator:string; + } diff --git a/utils/properties/searchFields_new.ts b/utils/properties/searchFields_new.ts new file mode 100644 index 00000000..fc5dd3ae --- /dev/null +++ b/utils/properties/searchFields_new.ts @@ -0,0 +1,164 @@ +export class SearchFields { + //main Entities + //RESULTS + //Used for datasets and publications + //In case Datasets should display different fields, use seperate tables for fields + public RESULT_REFINE_FIELDS = ["instancetypename", "resultlanguagename", "community","relproject", "relfunder", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id", + "resultacceptanceyear","resultbestlicense"];//,"collectedfrom"]; + + public RESULT_ADVANCED_FIELDS:string[] = ["q","resulttitle","relperson","resultpublisher","instancetypenameid", + "resultlanguageid", "community","relprojectid", "relfunder", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id", + "resultacceptanceyear","resultbestlicenseid","pid","resulthostingdatasourceid","collectedfromdatasourceid","relpersonid"]; + public RESULT_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["resulttitle"]:{name:"Title", type:"keyword", param:"title", equalityOperator: "="}, + ["relperson"]:{name:"Author", type:"keyword", param:"author", equalityOperator: "="}, + ["resultpublisher"]:{name:"Publisher", type:"keyword", param:"publisher", equalityOperator: "="}, + ["pid"]:{name:"PID", type:"keyword", param:"pid", equalityOperator: " = "}, + ["resulthostingdatasourceid"]:{name:"Hosting Data Provider", type:"entity", param:"hostedBy", equalityOperator: " exact "}, + ["relpersonid"]:{name:"Person", type:"entity", param:"person", equalityOperator: " exact "}, + ["instancetypename"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["instancetypenameid"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + ["resultlanguagename"]:{name:"Language", type:"refine", param:"lang", equalityOperator: " exact "}, + ["resultlanguageid"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + ["community"]:{name:"Community", type:"refine", param:"community", equalityOperator: " exact "}, + ["relproject"]:{name:"Project", type:"refine", param:"project", equalityOperator: " exact "}, + ["relprojectid"]:{name:"Project", type:"entity", param:"project", equalityOperator: " exact "}, + ["relfunder"]:{name:"Funder", type:"refine", param:"funder", equalityOperator: " exact "}, + ["relfundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", equalityOperator: " exact "}, + ["relfundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", equalityOperator: " exact "}, + ["relfundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", equalityOperator: " exact "}, + ["resultacceptanceyear"]:{name:"Year", type:"year", param:"year", equalityOperator: " exact "}, + ["resultbestlicense"]:{name:"Access Mode", type:"refine", param:"access", equalityOperator: " exact "}, + ["resultbestlicenseid"]:{name:"Access Mode", type:"vocabulary", param:"access", equalityOperator: " exact "}, + ["collectedfrom"]:{name:"Content Provider", type:"refine", param:"datasource", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + }; + + //PROJECT + + public PROJECT_REFINE_FIELDS:string[] = ["funder","fundinglevel0_id","fundinglevel1_id", + "fundinglevel2_id","projectstartyear","projectendyear","projectecsc39"]; + public PROJECT_ADVANCED_FIELDS:string[] = ["q","projectacronym","projecttitle","projectkeywords", + "funder", "fundinglevel0_id","fundinglevel1_id", "fundinglevel2_id", + "projectstartyear","projectendyear","projectecsc39", + "projectcode","relorganizationid", "collectedfromdatasourceid"]; + public PROJECT_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["projectacronym"]:{name:"Acronym", type:"keyword", param:"acronym", equalityOperator: "="}, + ["projecttitle"]:{name:"Title", type:"keyword", param:"title", equalityOperator: "="}, + ["projectkeywords"]:{name:"Keywords", type:"keyword", param:"keywords", equalityOperator: "="}, + + ["funder"]:{name:"Funder", type:"refine", param:"funder", equalityOperator: " exact "}, + ["fundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", equalityOperator: " exact "}, + ["fundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", equalityOperator: " exact "}, + ["fundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", equalityOperator: " exact "}, + ["projectstartyear"]:{name:"Start Year", type:"year", param:"startyear", equalityOperator: " exact "}, + ["projectendyear"]:{name:"End Year", type:"year", param:"endyear", equalityOperator: " exact "}, + + ["projectecsc39"]:{name:"Special Clause 39", type:"boolean", param:"sc39", equalityOperator: " exact "}, + ["projectcode"]:{name:"Project Code", type:"keyword", param:"code", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + + }; + + //DATAPROVIDERS + + public DATASOURCE_REFINE_FIELDS:string[] = ["datasourcetypeuiname", "datasourceodlanguages", "datasourceodcontenttypes", + "datasourcecompatibilityname"]; + public DATASOURCE_ADVANCED_FIELDS:string[] = ["q", "datasourceofficialname", + "datasourceenglishname","datasourceodsubjects", "datasourcetypeid","datasourceodlanguages", + "datasourceodcontenttypes", "datasourcecompatibilityid","relorganizationid", "collectedfromdatasourceid"]; + + public DATASOURCE_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["datasourceofficialname"]:{name:"English name", type:"keyword", param:"officialname", equalityOperator: "="}, + ["datasourceenglishname"]:{name:"Title", type:"keyword", param:"engname", equalityOperator: "="}, + ["datasourceodsubjects"]:{name:"Subject", type:"keyword", param:"subjects", equalityOperator: "="}, + ["datasourcetypeuiid"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["datasourcetypeuiname"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["datasourcetypeid"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + ["datasourceodlanguages"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + ["datasourceodcontenttypes"]:{name:"Content", type:"refine", param:"content", equalityOperator: " exact "}, + ["datasourcecompatibilityid"]:{name:"Compatibility Level", type:"vocabulary", param:"compatibility", equalityOperator: " exact "}, + ["datasourcecompatibilityname"]:{name:"Compatibility Level", type:"refine", param:"compatibility", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + + }; + + public COMPATIBLE_DATAPROVIDER_FIELDS:string[] = ["datasourcetypeuiid","datasourcecompatibilityid"]; + public ENTITY_REGISTRIES_FIELDS:string[] = ["datasourcetypeid","datasourcecompatibilityid"]; + + //ORGANIZATION + + public ORGANIZATION_REFINE_FIELDS:string[] = ["organizationcountryname"] + public ORGANIZATION_ADVANCED_FIELDS:string[] = ["q", + "organizationlegalname","organizationlegalshortname","organizationcountryid"]; + + public ORGANIZATION_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["organizationlegalname"]:{name:"Legal Name", type:"keyword", param:"name", equalityOperator: "="}, + ["organizationlegalshortname"]:{name:"Legal Short Name", type:"keyword", param:"shortname", equalityOperator: "="}, + ["organizationcountryid"]:{name:"Country", type:"vocabulary", param:"country", equalityOperator: "="}, + ["organizationcountryname"]:{name:"Country", type:"refine", param:"country", equalityOperator: "="} + }; + public ORGANIZATION_INDEX:string[] = ["organizationcountryname"]//,"organizationeclegalbody"]; + public ADVANCED_SEARCH_ORGANIZATION_PARAM:string[] = ["q","contenttype","compatibility","country","type"]; + public ORGANIZATION_INDEX_PARAM_MAP:{ [key:string]:string } = {["organizationlegalname"]:"contenttype", ["organizationlegalshortname"]:"type", + ["organizationcountryname"]:"country"};//,["organizationeclegalbody"]:"type"}; + public ORGANIZATION_FIELDS_MAP: { [key:string]:{ name:string, operator:string, type:string, indexField:string , equalityOperator:string}} ={ + ["q"]:{name:"All fields",operator:"op", type:"keyword", indexField:null, equalityOperator: "="}, + ["contenttype"]:{name:"Legal Name",operator:"cn", type:"keyword" , indexField:"organizationlegalname", equalityOperator: "="}, + ["compatibility"]:{name:"Legal Short Name",operator:"cm", type:"keyword", indexField:"organizationlegalshortname", equalityOperator: "="}, + ["country"]:{name:"Country",operator:"cu", type:"vocabulary", indexField:"organizationcountryname", equalityOperator: " exact "}, + ["type"]:{name:"Type",operator:"tp", type:"refine", indexField:"organizationeclegalbody", equalityOperator: " exact "}, + + }; + + //PERSON + public PERSON_REFINE_FIELDS:string[] = []; + public PERSON_ADVANCED_FIELDS:string[] = ["q","personsecondnames","personfirstname","personfullname"]; + public PERSON_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["personsecondnames"]:{name:"Surname", type:"keyword", param:"surname", equalityOperator: "="}, + ["personfirstname"]:{name:"First Name",type:"keyword", param:"name", equalityOperator: "="}, + ["personfullname"]:{name:"Full name", type:"keyword", param:"fullname", equalityOperator: "="} + }; + + + public HIDDEN_FIELDS:string[] = ["fundinglevel0_id","fundinglevel1_id","fundinglevel2_id", + "relfundinglevel0_id","relfundinglevel1_id,relfundinglevel2_id"]; + + public DEPENDENT_FIELDS: { [key:string]:string } = {["fundinglevel0_id"]:"funder", + ["fundinglevel1_id"]:"fundinglevel0_id", ["fundinglevel2_id"]:"fundinglevel1_id", ["relfundinglevel0_id"]:"relfunder", + ["relfundinglevel1_id"]:"relfundinglevel0_id", ["relfundinglevel2_id"]:"relfundinglevel1_id"}; + + + public ADVANCED_SEARCH_OPERATORS:[{name:string, id:string}] = [{name:"AND",id:"and"},{name:"OR",id:"or"},{name:"NOT",id:"not"}]; + + constructor (){ + } + getFieldName(fieldId:string,fieldType:string):string{ + if(fieldType == "publication" || fieldType == "dataset"){ + return this.RESULT_FIELDS[fieldId].name; + }else if(fieldType == "project"){ + return this.PROJECT_FIELDS[fieldId].name; + }else if(fieldType == "organization"){ + return this.ORGANIZATION_FIELDS[fieldId].name; + }else if(fieldType == "datasource"){ + return this.DATASOURCE_FIELDS[fieldId].name; + }else{ + return "UNDEFINED"; + } + } +} +export class FieldDetails{ + name:string; + type:string; + param:string; + equalityOperator:string; + } diff --git a/utils/properties/searchFields_old.ts b/utils/properties/searchFields_old.ts new file mode 100644 index 00000000..9c74982a --- /dev/null +++ b/utils/properties/searchFields_old.ts @@ -0,0 +1,164 @@ +export class SearchFields { + //main Entities + //RESULTS + //Used for datasets and publications + //In case Datasets should display different fields, use seperate tables for fields + public RESULT_REFINE_FIELDS = ["instancetypename", "resultlanguagename", "community","relproject", "relfunderid", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id", + "resultacceptanceyear","resultbestlicense"];//,"collectedfrom"]; + + public RESULT_ADVANCED_FIELDS:string[] = ["q","resulttitle","relperson","resultpublisher","instancetypenameid", + "resultlanguageid", "community","relprojectid", "relfunderid", + "relfundinglevel0_id","relfundinglevel1_id","relfundinglevel2_id", + "resultacceptanceyear","resultbestlicenseid","pid","resulthostingdatasourceid","collectedfromdatasourceid","relpersonid"]; + public RESULT_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["resulttitle"]:{name:"Title", type:"keyword", param:"title", equalityOperator: "="}, + ["relperson"]:{name:"Author", type:"keyword", param:"author", equalityOperator: "="}, + ["resultpublisher"]:{name:"Publisher", type:"keyword", param:"publisher", equalityOperator: "="}, + ["pid"]:{name:"PID", type:"keyword", param:"pid", equalityOperator: " = "}, + ["resulthostingdatasourceid"]:{name:"Hosting Data Provider", type:"entity", param:"hostedBy", equalityOperator: " exact "}, + ["relpersonid"]:{name:"Person", type:"entity", param:"person", equalityOperator: " exact "}, + ["instancetypename"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["instancetypenameid"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + ["resultlanguagename"]:{name:"Language", type:"refine", param:"lang", equalityOperator: " exact "}, + ["resultlanguageid"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + ["community"]:{name:"Community", type:"refine", param:"community", equalityOperator: " exact "}, + ["relproject"]:{name:"Project", type:"refine", param:"project", equalityOperator: " exact "}, + ["relprojectid"]:{name:"Project", type:"entity", param:"project", equalityOperator: " exact "}, + ["relfunderid"]:{name:"Funder", type:"refine", param:"funder", equalityOperator: " exact "}, + ["relfundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", equalityOperator: " exact "}, + ["relfundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", equalityOperator: " exact "}, + ["relfundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", equalityOperator: " exact "}, + ["resultacceptanceyear"]:{name:"Year", type:"year", param:"year", equalityOperator: " exact "}, + ["resultbestlicense"]:{name:"Access Mode", type:"refine", param:"access", equalityOperator: " exact "}, + ["resultbestlicenseid"]:{name:"Access Mode", type:"vocabulary", param:"access", equalityOperator: " exact "}, + ["collectedfrom"]:{name:"Content Provider", type:"refine", param:"datasource", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + }; + + //PROJECT + + public PROJECT_REFINE_FIELDS:string[] = ["funderid","fundinglevel0_id","fundinglevel1_id", + "fundinglevel2_id","projectstartyear","projectendyear","projectecsc39"]; + public PROJECT_ADVANCED_FIELDS:string[] = ["q","projectacronym","projecttitle","projectkeywords", + "funderid", "fundinglevel0_id","fundinglevel1_id", "fundinglevel2_id", + "projectstartyear","projectendyear","projectecsc39", + "projectcode","relorganizationid", "collectedfromdatasourceid"]; + public PROJECT_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["projectacronym"]:{name:"Acronym", type:"keyword", param:"acronym", equalityOperator: "="}, + ["projecttitle"]:{name:"Title", type:"keyword", param:"title", equalityOperator: "="}, + ["projectkeywords"]:{name:"Keywords", type:"keyword", param:"keywords", equalityOperator: "="}, + + ["funderid"]:{name:"Funder", type:"refine", param:"funder", equalityOperator: " exact "}, + ["fundinglevel0_id"]:{name:"Funding Stream", type:"refine", param:"funderlv0", equalityOperator: " exact "}, + ["fundinglevel1_id"]:{name:"Funding Substream level 1", type:"refine", param:"funderlv1", equalityOperator: " exact "}, + ["fundinglevel2_id"]:{name:"Funding Substream level 2", type:"refine", param:"funderlv2", equalityOperator: " exact "}, + ["projectstartyear"]:{name:"Start Year", type:"year", param:"startyear", equalityOperator: " exact "}, + ["projectendyear"]:{name:"End Year", type:"year", param:"endyear", equalityOperator: " exact "}, + + ["projectecsc39"]:{name:"Special Clause 39", type:"boolean", param:"sc39", equalityOperator: " exact "}, + ["projectcode"]:{name:"Project Code", type:"keyword", param:"code", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + + }; + + //DATAPROVIDERS + + public DATASOURCE_REFINE_FIELDS:string[] = ["datasourcetypeuiname", "datasourceodlanguages", "datasourceodcontenttypes", + "datasourcecompatibilityname"]; + public DATASOURCE_ADVANCED_FIELDS:string[] = ["q", "datasourceofficialname", + "datasourceenglishname","datasourceodsubjects", "datasourcetypeid","datasourceodlanguages", + "datasourceodcontenttypes", "datasourcecompatibilityid","relorganizationid", "collectedfromdatasourceid"]; + + public DATASOURCE_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["datasourceofficialname"]:{name:"English name", type:"keyword", param:"officialname", equalityOperator: "="}, + ["datasourceenglishname"]:{name:"Title", type:"keyword", param:"engname", equalityOperator: "="}, + ["datasourceodsubjects"]:{name:"Subject", type:"keyword", param:"subjects", equalityOperator: "="}, + ["datasourcetypeuiid"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["datasourcetypeuiname"]:{name:"Type", type:"refine", param:"type", equalityOperator: " exact "}, + ["datasourcetypeid"]:{name:"Type", type:"vocabulary", param:"type", equalityOperator: " exact "}, + ["datasourceodlanguages"]:{name:"Language", type:"vocabulary", param:"lang", equalityOperator: " exact "}, + ["datasourceodcontenttypes"]:{name:"Content", type:"refine", param:"content", equalityOperator: " exact "}, + ["datasourcecompatibilityid"]:{name:"Compatibility Level", type:"vocabulary", param:"compatibility", equalityOperator: " exact "}, + ["datasourcecompatibilityname"]:{name:"Compatibility Level", type:"refine", param:"compatibility", equalityOperator: " exact "}, + ["relorganizationid"]:{name:"Organization", type:"entity", param:"organization", equalityOperator: " exact "}, + ["collectedfromdatasourceid"]:{name:"Collected from Content Provider", type:"entity", param:"collectedFrom", equalityOperator: " exact "} + + }; + + public COMPATIBLE_DATAPROVIDER_FIELDS:string[] = ["datasourcetypeuiid","datasourcecompatibilityid"]; + public ENTITY_REGISTRIES_FIELDS:string[] = ["datasourcetypeid","datasourcecompatibilityid"]; + + //ORGANIZATION + + public ORGANIZATION_REFINE_FIELDS:string[] = ["organizationcountryname"] + public ORGANIZATION_ADVANCED_FIELDS:string[] = ["q", + "organizationlegalname","organizationlegalshortname","organizationcountryid"]; + + public ORGANIZATION_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["organizationlegalname"]:{name:"Legal Name", type:"keyword", param:"name", equalityOperator: "="}, + ["organizationlegalshortname"]:{name:"Legal Short Name", type:"keyword", param:"shortname", equalityOperator: "="}, + ["organizationcountryid"]:{name:"Country", type:"vocabulary", param:"country", equalityOperator: "="}, + ["organizationcountryname"]:{name:"Country", type:"refine", param:"country", equalityOperator: "="} + }; + public ORGANIZATION_INDEX:string[] = ["organizationcountryname"]//,"organizationeclegalbody"]; + public ADVANCED_SEARCH_ORGANIZATION_PARAM:string[] = ["q","contenttype","compatibility","country","type"]; + public ORGANIZATION_INDEX_PARAM_MAP:{ [key:string]:string } = {["organizationlegalname"]:"contenttype", ["organizationlegalshortname"]:"type", + ["organizationcountryname"]:"country"};//,["organizationeclegalbody"]:"type"}; + public ORGANIZATION_FIELDS_MAP: { [key:string]:{ name:string, operator:string, type:string, indexField:string , equalityOperator:string}} ={ + ["q"]:{name:"All fields",operator:"op", type:"keyword", indexField:null, equalityOperator: "="}, + ["contenttype"]:{name:"Legal Name",operator:"cn", type:"keyword" , indexField:"organizationlegalname", equalityOperator: "="}, + ["compatibility"]:{name:"Legal Short Name",operator:"cm", type:"keyword", indexField:"organizationlegalshortname", equalityOperator: "="}, + ["country"]:{name:"Country",operator:"cu", type:"vocabulary", indexField:"organizationcountryname", equalityOperator: " exact "}, + ["type"]:{name:"Type",operator:"tp", type:"refine", indexField:"organizationeclegalbody", equalityOperator: " exact "}, + + }; + + //PERSON + public PERSON_REFINE_FIELDS:string[] = []; + public PERSON_ADVANCED_FIELDS:string[] = ["q","personsecondnames","personfirstname","personfullname"]; + public PERSON_FIELDS: { [key:string]:FieldDetails}={ + ["q"]:{name:"All fields", type:"keyword", param:"q", equalityOperator: "="}, + ["personsecondnames"]:{name:"Surname", type:"keyword", param:"surname", equalityOperator: "="}, + ["personfirstname"]:{name:"First Name",type:"keyword", param:"name", equalityOperator: "="}, + ["personfullname"]:{name:"Full name", type:"keyword", param:"fullname", equalityOperator: "="} + }; + + + public HIDDEN_FIELDS:string[] = ["fundinglevel0_id","fundinglevel1_id","fundinglevel2_id", + "relfundinglevel0_id","relfundinglevel1_id,relfundinglevel2_id"]; + + public DEPENDENT_FIELDS: { [key:string]:string } = {["fundinglevel0_id"]:"funderid", + ["fundinglevel1_id"]:"fundinglevel0_id", ["fundinglevel2_id"]:"fundinglevel1_id", ["relfundinglevel0_id"]:"relfunderid", + ["relfundinglevel1_id"]:"relfundinglevel0_id", ["relfundinglevel2_id"]:"relfundinglevel1_id"}; + + + public ADVANCED_SEARCH_OPERATORS:[{name:string, id:string}] = [{name:"AND",id:"and"},{name:"OR",id:"or"},{name:"NOT",id:"not"}]; + + constructor (){ + } + getFieldName(fieldId:string,fieldType:string):string{ + if(fieldType == "publication" || fieldType == "dataset"){ + return this.RESULT_FIELDS[fieldId].name; + }else if(fieldType == "project"){ + return this.PROJECT_FIELDS[fieldId].name; + }else if(fieldType == "organization"){ + return this.ORGANIZATION_FIELDS[fieldId].name; + }else if(fieldType == "datasource"){ + return this.DATASOURCE_FIELDS[fieldId].name; + }else{ + return "UNDEFINED"; + } + } +} +class FieldDetails{ + name:string; + type:string; + param:string; + equalityOperator:string; + } diff --git a/utils/routerHelper.class.ts b/utils/routerHelper.class.ts new file mode 100644 index 00000000..fecaf296 --- /dev/null +++ b/utils/routerHelper.class.ts @@ -0,0 +1,34 @@ + + + +export class RouterHelper { + //Use this class function to create queryParams Objects in format {key1:value1} or {key1:value1,key2:value2,key3:value3,...} for multiple parameters + constructor(){} + // Link + public createQueryParam(key:string,value:string){ + var obj ={}; + obj[key]=value; + return obj; + + } + public createQueryParamsPaging(keys:string[],values:string[],pageParameter:string,pageValue:number){ + var obj = this.createQueryParams(keys, values); + obj[pageParameter] = ""+pageValue; + return obj; + + } + public createQueryParams(keys:string[],values:string[]){ + var obj ={}; + if(!keys || !values || keys.length != values.length){ + return obj; + }else{ + for(var i=0; i< keys.length; i++){ + obj[keys[i]]=values[i]; + } + } + return obj; + + } + + +} diff --git a/utils/staticAutoComplete/ISVocabularies.service.ts b/utils/staticAutoComplete/ISVocabularies.service.ts new file mode 100644 index 00000000..7ec5902e --- /dev/null +++ b/utils/staticAutoComplete/ISVocabularies.service.ts @@ -0,0 +1,110 @@ +import {Injectable} from '@angular/core'; +import {Http, Response} from '@angular/http'; +import {Observable} from 'rxjs/Observable'; +import {AutoCompleteValue} from '../../searchPages/searchUtils/searchHelperClasses.class'; +import 'rxjs/add/observable/of'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/share'; + +import {OpenaireProperties} from '../../utils/properties/openaireProperties'; + +@Injectable() +export class ISVocabulariesService { + private api =OpenaireProperties.getVocabulariesAPI(); + constructor(private http: Http ) {} + + getVocabularyByType(field:string,entity:string):any{ + console.log("getVocabulary field: "+ field + " for entity: "+ entity); + var file = ""; + var vocabulary = ""; + if( field == "lang"){ + // file="languages.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:languages.json"; + return this.getVocabularyFromService(vocabulary); + }else if ( field == "type" && (entity == "publication")){ + // file = "publicationTypes.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:publication_resource.json"; + return this.getVocabularyFromService(vocabulary); + + }else if ( field == "type" && (entity == "dataset")){ + // file = "dnet:dataCite_resource.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:dataCite_resource.json"; + return this.getVocabularyFromService(vocabulary); + + }else if( field == "access" && (entity == "publication" || entity == "dataset")){ + // file= "accessMode.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:access_modes.json"; + return this.getVocabularyFromService(vocabulary); + + } else if( (field == "type") && (entity == "dataprovider")){ + // file = "dataProviderType.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:datasource_typologies.json"; + return this.getVocabularyFromService(vocabulary); + + } else if( field == "compatibility" && (entity == "dataprovider")){ + // file = "dataProviderCompatibility.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:datasourceCompatibilityLevel.json"; + return this.getVocabularyFromService(vocabulary); + + } else if( field == "country" ){ + // file = "countries.json"; + // return this.getVocabularyFromFile(file); + vocabulary = "dnet:countries.json"; + return this.getVocabularyFromService(vocabulary); + + } + return null; + + } + // getVocabularyFromFile (file:string):AutoCompleteValue[] { + // var lang = JSON.parse(JSON.stringify(require('../utils/vocabularies/'+file))); + // return this.parse(lang["terms"]); + // } + getVocabularyFromService (vocabularyName:string):any { + let url = this.api + vocabularyName; + console.log(url); + + // return this.http.get(url).toPromise() + // .then(request => + // { + // request = request.json()['terms']; + // var results:AutoCompleteValue[] = this.parse(request); + // console.log("Get vocabulary : "+ vocabularyName+ " - get " +results.length+ "results"); + // return results; + // }); + return this.http.get((OpenaireProperties.isCacheEnabled())? (OpenaireProperties.getCacheUrl()+encodeURIComponent(url)): url) + .do(res => console.log(res)) + .map(res => res.json()) + .map(res => res['terms']) + .do(res => console.log(res)) + .map(res => this.parse(res)) + .do(res => console.log(res)) + .catch(this.handleError); + + } + + parse (data: any):AutoCompleteValue[] { + var array:AutoCompleteValue[] =[] + for(var i = 0; i < data.length; i++){ + var value:AutoCompleteValue = new AutoCompleteValue(); + value.id = data[i].englishName;//data[i].code; + value.label = data[i].englishName; + array.push(value); + } + + return array; + + } +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.log(error); + return Observable.throw(error || 'Server error'); + } +} diff --git a/utils/staticAutoComplete/staticAutoComplete.component.ts b/utils/staticAutoComplete/staticAutoComplete.component.ts new file mode 100644 index 00000000..49db0739 --- /dev/null +++ b/utils/staticAutoComplete/staticAutoComplete.component.ts @@ -0,0 +1,299 @@ +import {Component, ElementRef, Input, Output, EventEmitter, OnChanges, SimpleChange} from '@angular/core'; +import {Value} from '../../searchPages/searchUtils/searchHelperClasses.class'; +import {ISVocabulariesService} from './ISVocabularies.service'; +import {RefineFieldResultsService} from '../../services/refineFieldResults.service'; +//Usage example +// + +@Component({ + selector: 'static-autocomplete', + host: { + '(document:click)': 'handleClick($event)', + }, + template: ` + + + {{showItem(item)}} + + + + + +
    +
      +
    • + Loading... + {{results}} results found: + No results found +
    • +
    • + {{showItem(item)}} +
    • +
    +
    +
    + + ` +}) +export class StaticAutoCompleteComponent implements OnChanges{ + @Input() placeHolderMessage = "Search for entries"; + @Input() title = "Autocomplete"; + @Output() addItem = new EventEmitter(); // when selected list changes update parent component + @Output() selectedValueChanged = new EventEmitter(); // when changed a method for filtering will be called + @Output() listUpdated = 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 allowDuplicates:boolean = false; + @Input() public selectedValue:string = ''; + @Input() public vocabularyId:string ; + @Input() public fieldName:string ; + @Input() public entityName:string ; + @Input() public fieldId:string ; + + @Input() public keyword = ''; + @Input() public type = 'search' //search, result, context, project + public warningMessage = ""; + public infoMessage = ""; + public showLoading:boolean = false; + public tries = 0; + public showInput = true; + public sub; + public done = false; + public results = 0; + public focus:boolean = false; + public currentFieldId: string ; + constructor ( private _vocabulariesService: ISVocabulariesService,private _refineService: RefineFieldResultsService, private myElement: ElementRef) { + this.currentFieldId=this.fieldId; + + } + ngOnDestroy(){ + if(this.sub && this.sub != undefined){ + this.sub.unsubscribe(); + } + } + + ngOnChanges(changes: {[propKey: string]: SimpleChange}) { + if(this.currentFieldId!=this.fieldId){ //this is going to be called when + this.currentFieldId=this.fieldId; + this.initialize(); + } + } + private initialize(){ + + this.showInput = true; + if(this.list == undefined || this.list.length == 0){ + this.showLoading = true; + + if(this.vocabularyId){ + // this.list = this._vocabulariesService.getVocabularyByType(this.vocabularyId, this.entityName); + // this.afterListFetchedActions(); + this.sub = this._vocabulariesService.getVocabularyByType(this.vocabularyId, this.entityName).subscribe( + data => { + this.list = data; + this.afterListFetchedActions(); + + }, + err => { + console.log(err); + this.warningMessage = "An Error occured..." + } + ); + }else if(this.fieldName && this.entityName){ + // this.list = this._refineService.getRefineFieldResultsByFieldName(this.fieldName,this.entityName); + this.sub = this._refineService.getRefineFieldResultsByFieldName(this.fieldName,this.entityName).subscribe( + data => { + this.list = data; + this.afterListFetchedActions(); + + }, + err => { + console.log(err); + this.warningMessage = "An Error occured..." + } + ); + }else{ + this.showLoading = false; + + } + }else{ + this.afterListFetchedActions(); + } + + } + public updateList(list){ // used in claim context autocomplete + this.list = list; + this.afterListFetchedActions() + } + private afterListFetchedActions(){ + this.showLoading = false; + this.getSelectedNameFromGivenId(); + this.listUpdated.emit({ + value: this.list + }); + if(this.list == null || this.list.length == 0 ){ + this.warningMessage = "No results available"; + return; + } + this.done = true; + if(this.keyword != ""){ + this.filter(); + } + + } + filter() { + this.focus = true; + if(this.done){ + this.infoMessage = ""; + this.filtered = []; + if(this.keyword == ""){ + var cut = 10; + if(this.list.length < 5){ + cut = this.list.length; + } + this.results = 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{ + this.tries = 0; + this.warningMessage = ""; + this.filtered = this.list.filter(function(el){ + return el.label.toLowerCase().indexOf(this.keyword.toLowerCase()) > -1; + }.bind(this)); + var cut = 10; + if(this.filtered .length < 5){ + cut = this.list.length; + } + this.results = this.filtered.length; + this.filtered =this.filtered.slice(0, cut); + } + } + } + remove(item:any){ + var index:number =this.checkIfExists(item,this.selected); + if (index > -1) { + this.selected.splice(index, 1); + } + if(!this.multipleSelections && this.selected.length == 0 ){ + this.showInput = true; + this.selectedValue = ""; + this.selectedValueChanged.emit({ + value: this.selectedValue + }); + + + } + } + select(item:any){ + // console.log("select"+this.selected.length + item.id + " "+ item.label); + + if(this.multipleSelections){ + var index:number =this.checkIfExists(item,this.selected); + if (index > -1 && !this.allowDuplicates) { + this.keyword = ""; + this.filtered.splice(0, this.filtered.length); + return; + } + else{ + this.selected.push(item); + this.keyword = ""; + this.filtered.splice(0, this.filtered.length); + this.addItem.emit({ + value: item + }); + } + }else{ + this.selected.splice(0, this.selected.length); + this.selected.push(item); + this.filtered.splice(0, this.filtered.length); + this.keyword = ""; + this.showInput = false; + this.selectedValue = item.id; + this.selectedValueChanged.emit({ + value: this.selectedValue + }); + + } + + } + private checkIfExists(item:any,list):number{ + + if(item.concept && item.concept.id ){ + + for (var _i = 0; _i < list.length; _i++) { + let itemInList = list[_i]; + if(item.concept.id == itemInList.concept.id){ + return _i; + } + } + }else if(item.id){ + for (var _i = 0; _i < list.length; _i++) { + let itemInList = list[_i]; + if(item.id == itemInList.id){ + return _i; + } + } + } + return -1; + + } + showItem(item:any):string{ + + if (item.name){ //search + return item.name; + }else if( item.concept && item.concept.label){ //context + return item.concept.label; + }else if (item.label){ //simple + return item.label; + } + + } + truncate(str:string, size:number):string{ + if(str == null){return "";} + return (str.length > size)?str.substr(0,size)+'...':str; + } + private getSelectedNameFromGivenId(){ + if(this.list == null ){ + return; + } + this.showInput = true; + 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; + return; + + } + } + } + + handleClick(event){ + var clickedComponent = event.target; + var inside = false; + do { + if (clickedComponent === this.myElement.nativeElement) { + inside = true; + } + clickedComponent = clickedComponent.parentNode; + } while (clickedComponent); + if(!inside){ + this.focus =false; + this.filtered.splice(0, this.filtered.length); + } + } + +} diff --git a/utils/staticAutoComplete/staticAutoComplete.module.ts b/utils/staticAutoComplete/staticAutoComplete.module.ts new file mode 100644 index 00000000..1c876a15 --- /dev/null +++ b/utils/staticAutoComplete/staticAutoComplete.module.ts @@ -0,0 +1,22 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import {StaticAutoCompleteComponent} from './staticAutoComplete.component'; +import {RefineFieldResultsServiceModule} from '../../services/refineFieldResultsService.module'; +import {ISVocabulariesService} from './ISVocabularies.service'; + + +@NgModule({ + imports: [ + CommonModule, FormsModule, RefineFieldResultsServiceModule + ], + declarations: [ + StaticAutoCompleteComponent + ], + exports: [ + StaticAutoCompleteComponent + ], + providers:[ ISVocabulariesService] +}) +export class StaticAutocompleteModule { } diff --git a/utils/string-utils.class.ts b/utils/string-utils.class.ts new file mode 100644 index 00000000..ece1ce3e --- /dev/null +++ b/utils/string-utils.class.ts @@ -0,0 +1,129 @@ +export class Dates { + public static isValidYear(yearString){ + // First check for the pattern + if(!/^\d{4}$/.test(yearString)) + return false; + var year = parseInt(yearString, 10); + + // Check the ranges of month and year + if(year < 1000 || year > 3000 ) + return false; + return true; + } + //format YYYY-MM-DD + public static isValidDate(dateString:string) + { + // First check for the pattern + if(!/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(dateString)) + return false; + + // Parse the date parts to integers + var parts = dateString.split("-"); + var day = parseInt(parts[2], 10); + var month = parseInt(parts[1], 10); + var year = parseInt(parts[0], 10); + if(!this.isValidYear(parts[0])){ + return false; + } + + // Check the ranges of month and year + if( month == 0 || month > 12) + return false; + + var monthLength = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; + + // Adjust for leap years + if(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)) + monthLength[1] = 29; + + // Check the range of the day + return day > 0 && day <= monthLength[month - 1]; + + } + public static getDateToday():Date{ + var myDate = new Date(); + return myDate; + + } + public static getDateToString(myDate:Date):string{ + var date:string = myDate.getFullYear()+ "-" ; + date+=((myDate.getMonth() + 1)<10)?"0"+(myDate.getMonth() + 1):(myDate.getMonth() + 1) ; + date+="-"; + date+= (myDate.getDate() <10 )? "0"+myDate.getDate():myDate.getDate() ; + return date; + + } + public static getDateXMonthsAgo(x:number):Date{ + var myDate = new Date(); + myDate.setMonth(myDate.getMonth() - x); + return myDate; + + } + public static getDateXYearsAgo(x:number):Date{ + var myDate = new Date(); + myDate.setFullYear(myDate.getFullYear() - x); + return myDate; + + } + public static getDateFromString(date:string):Date{ + + var myDate = new Date(); + myDate.setFullYear(+date.substring(0,4)); + myDate.setMonth(+date.substring(5,7)-1); + myDate.setDate(+date.substring(8,11)) + return myDate; + + } + +} + +export class DOI{ + + public static getDOIsFromString(str:string):string[]{ + var DOIs:string[] = []; + var words:string[] = str.split(" "); + + for(var i=0; i< words.length; i++){ + if(DOI.isValidDOI(words[i]) && DOIs.indexOf(words[i]) == -1){ + DOIs.push(words[i]); + } + } + return DOIs; + } + public static isValidDOI(str:string):boolean{ + + var exp1 = /\b(10[.][0-9]{4,}(?:[.][0-9]+)*\/(?:(?!["&\'<>])\S)+)\b/g + var exp2 = /\b(10[.][0-9]{4,}(?:[.][0-9]+)*\/(?:(?!["&\'<>])[[:graph:]])+)\b/g + if(str.match(exp1)!=null || str.match(exp2)!=null){ + // console.log("It's a DOI"); + return true; + } + return false; + + } +} +export class StringUtils{ + public static quote(params: string):string { + return '"'+params+'"'; + } + + public static unquote(params: string):string { + if(params.length > 2 && (params[0]=='"' && params[params.length-1]=='"') || (params[0]=="'" && params[params.length-1]=="'")){ + params= params.substring(1, params.length-1); + } + return params; + } + public static URIEncode(params: string):string { + return encodeURIComponent(params); + } + public static URIDecode(params: string):string { + return decodeURIComponent(params); + } + public static b64DecodeUnicode(str) { + return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }).join('')); + } + + +}