diff --git a/portal-2/src/app/app-routing.module.ts b/portal-2/src/app/app-routing.module.ts index cf75438a..6c6997d2 100644 --- a/portal-2/src/app/app-routing.module.ts +++ b/portal-2/src/app/app-routing.module.ts @@ -106,7 +106,7 @@ export function gethtmlProjectReportModule() { return System.import('./landingPages/htmlProjectReport/htmlProjectReport.module' + (process.env.AOT ? '.ngfactory' : '')) .then(mod => mod[(process.env.AOT ? 'HtmlProjectReportModuleNgFactory' : 'HtmlProjectReportModule')]); } -/*export function getMyClaimsModule() { +export function getMyClaimsModule() { return System.import('./claims/myClaims/myClaims.module' + (process.env.AOT ? '.ngfactory' : '')) .then(mod => mod[(process.env.AOT ? 'MyClaimsModuleNgFactory' : 'MyClaimsModule')]); } @@ -122,7 +122,11 @@ export function getLinkingModule() { export function getBulkLinkingModule() { return System.import('./claims/linking/bulkLinking.module' + (process.env.AOT ? '.ngfactory' : '')) .then(mod => mod[(process.env.AOT ? 'BulkLinkingModuleNgFactory' : 'BulkLinkingModule')]); -}*/ +} +export function getDirectLinkingModule() { + return System.import('./claims/directLinking/directLinking.module' + (process.env.AOT ? '.ngfactory' : '')) + .then(mod => mod[(process.env.AOT ? 'DirectLinkingModuleNgFactory' : 'DirectLinkingModule')]); +} @NgModule({ imports: [ RouterModule.forChild([ @@ -164,10 +168,11 @@ export function getBulkLinkingModule() { { path: 'search/advanced/projects', loadChildren: getAdvancedSearchProjectsModule }, { path: 'search/advanced/people', loadChildren: getAdvancedSearchPeopleModule }, { path: 'project-report', loadChildren: gethtmlProjectReportModule }, - // { path: 'myclaims', loadChildren: getMyClaimsModule }, - // { path: 'claims', loadChildren: getClaimsAdminModule }, - // { path: 'participate/bulk-claim', loadChildren: getBulkLinkingModule }, - // { path: 'participate/claim', loadChildren: getLinkingModule }, + /*{ path: 'myclaims', loadChildren: getMyClaimsModule }, + { path: 'claims', loadChildren: getClaimsAdminModule }, + { path: 'participate/bulk-claim', loadChildren: getBulkLinkingModule }, + { path: 'participate/claim', loadChildren: getLinkingModule }, + { path: 'participate/direct-claim', loadChildren: getDirectLinkingModule },*/ ]) ], }) diff --git a/portal-2/src/app/claims/claim-utils/claimContext.component.ts b/portal-2/src/app/claims/claim-utils/claimContextSearchForm.component.ts similarity index 53% rename from portal-2/src/app/claims/claim-utils/claimContext.component.ts rename to portal-2/src/app/claims/claim-utils/claimContextSearchForm.component.ts index 7bbdb837..75deaf7e 100644 --- a/portal-2/src/app/claims/claim-utils/claimContext.component.ts +++ b/portal-2/src/app/claims/claim-utils/claimContextSearchForm.component.ts @@ -7,87 +7,43 @@ declare var UIkit:any; @Component({ // moduleId: module.id, - selector: 'claim-contexts', + selector: 'claim-contexts-search-form', template: ` -
-
- - - + +
- + + +
+ - - - - -
+ +
+ +
-
-
-
-
- - -
-
- - -
- - -
-
- - - ` }) -export class ClaimContextComponent { -@Input() public inline:boolean = false ; // for claimed started from landing pages -@Input() public showComponent:boolean = true ; // for claimed started from landing pages +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 = []; -@Input() public selectedCommunityId:string = "0"; -@Input() public selectedCategoryId:string ="0"; -@Output() cselectedCommunityChange = new EventEmitter(); -@Output() selectedCategoryChange = new EventEmitter(); +public selectedCommunityId:string = "0"; +public selectedCategoryId:string ="0"; +@Output() contextSelected = new EventEmitter(); + @ViewChild (StaticAutoCompleteComponent) autocomplete : StaticAutoCompleteComponent ; public query = ''; @@ -123,6 +79,9 @@ select($event){ } // var UIkit:any; if (!found) { + this.contextSelected.emit({ + value: true + }); this.selectedList.push(context); UIkit.notify({ message : 'A context is selected.', diff --git a/portal-2/src/app/claims/claim-utils/claimContext.module.ts b/portal-2/src/app/claims/claim-utils/claimContextSearchForm.module.ts similarity index 64% rename from portal-2/src/app/claims/claim-utils/claimContext.module.ts rename to portal-2/src/app/claims/claim-utils/claimContextSearchForm.module.ts index 4b5a7605..ae3a5d8e 100644 --- a/portal-2/src/app/claims/claim-utils/claimContext.module.ts +++ b/portal-2/src/app/claims/claim-utils/claimContextSearchForm.module.ts @@ -1,7 +1,7 @@ import { NgModule } from '@angular/core'; import { SharedModule } from '../../shared/shared.module'; -import { ClaimContextComponent } from './claimContext.component'; +import { ClaimContextSearchFormComponent } from './claimContextSearchForm.component'; import{ContextsServiceModule} from './service/contextsService.module'; import {StaticAutocompleteModule} from '../../utils/staticAutoComplete/staticAutoComplete.module'; @@ -13,7 +13,7 @@ import { ClaimContextComponent } from './claimContext.component'; ], declarations: [ - ClaimContextComponent - ], exports: [ClaimContextComponent ] + ClaimContextSearchFormComponent + ], exports: [ClaimContextSearchFormComponent ] }) -export class ClaimContextModule { } +export class ClaimContextSearchFormModule { } diff --git a/portal-2/src/app/claims/claim-utils/claimDataset.component.ts b/portal-2/src/app/claims/claim-utils/claimDataset.component.ts deleted file mode 100644 index c8f7f854..00000000 --- a/portal-2/src/app/claims/claim-utils/claimDataset.component.ts +++ /dev/null @@ -1,247 +0,0 @@ -import { Component, Input, Output, EventEmitter} from '@angular/core'; -import { SearchDataciteService } from '../claim-utils/service/searchDatacite.service'; -import {SearchDatasetsService} from '../../services/searchDatasets.service'; -import {ClaimResult} from '../claim-utils/claimEntities.class'; -import { ErrorCodes} from '../../utils/properties/openaireProperties'; -import{DOI} from '../../utils/string-utils.class'; - - -@Component({ - selector: 'claim-dataset', - template: ` - - - -
-
- - - -
- - ` -}) -export class ClaimDatasetComponent { - constructor (private _searchDataciteService: SearchDataciteService, private _searchDatasetsService:SearchDatasetsService){ - 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(this.keyword,this.size,1); - } -} - -@Input() public select:boolean = true ; -@Input() public keyword:string = ''; -@Input() public selectedDatasets = [] ; -@Output() datasetsChange = new EventEmitter(); - public size:number = 10; - public navigateTo: string = "Search"; - public source: string = "datacite"; - public type : string = "dataset"; - public errorCodes:ErrorCodes = new ErrorCodes(); - - dataciteResults=[]; - dataciteResultsNum:number = null; - // dataciteResultsNum : Observable = null; - dataciteStatus = this.errorCodes.NONE; - datacitePage : number = 1; - - openaireResults=[]; - openaireResultsNum:number = 0 ; - openaireStatus = this.errorCodes.NONE; - openairePage : number = 1; - - public warningMessage = ""; - public infoMessage = ""; - - public todayDate = ''; - public nextDate = ''; - public DOIs:string[] = []; - - public search(term: string, size : number, page : number){ - this.DOIs = DOI.getDOIsFromString(term); - this.searchDatacite(term,10,1); - this.searchOpenaire(term,10,1); - } - private searchDatacite (term: string, size : number, page : number) { - this.getDataciteResults(term,size,page); - this.warningMessage = ""; - this.infoMessage = ""; - - } - private searchOpenaire (term: string, size : number, page : number) { - if(this.DOIs.length > 0 ){ - this.openaireStatus = this.errorCodes.LOADING; - this._searchDatasetsService.searchDatasetsByDois(this.DOIs, null, page, size, []).subscribe( - data => { - if(data != null) { - this.openairePage=page; - this.openaireResultsNum = data[0]; - this.openaireResults = data[1]; - this.openaireStatus = this.errorCodes.DONE; - if(this.openaireResultsNum == 0){ - this.openaireStatus = this.errorCodes.NONE; - } - } - }, - err => { - this.openaireStatus = this.errorCodes.ERROR; - console.log(err.status); - } - ); - }else{ - this._searchDatasetsService.searchDatasets('q='+term+'', null, page, size, []).subscribe( - data => { - if(data != null) { - this.openairePage=page; - this.openaireResultsNum = data[0]; - this.openaireResults = data[1]; - this.openaireStatus = this.errorCodes.DONE; - if(this.openaireResultsNum == 0){ - this.openaireStatus = this.errorCodes.NONE; - } - } - }, - err => { - this.openaireStatus = 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.docs; - this.datacitePage=page; - this.dataciteResultsNum = data.numFound; - this.dataciteStatus = this.errorCodes.DONE; - - - }, - err => { - this.dataciteStatus = this.errorCodes.ERROR; - console.log(err); - } - - ); - } - - add(item, itemId,itemType,itemSource,itemTitle, itemUrl, date, accessmode){ - console.log(' adding dataset '+ itemSource+" "+ itemTitle); - var result: ClaimResult ; - if(itemSource == 'datacite'){ - 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}; - } - var found:boolean = this.isSelected( result.id); - this.warningMessage = ""; - if (!found) { - this.selectedDatasets.push(result); - this.datasetsChange.emit({ - value: this.selectedDatasets - }); - }else{ - this.warningMessage = "Dataset already in selected list"; - } - - } - - - datacitePageChange($event) { - this.datacitePage=$event.value; - this.dataciteResults=[]; - this.searchDatacite(this.keyword,10,this.datacitePage); - this.warningMessage = ""; - this.infoMessage = ""; - - } - openairePageChange($event) { - this.openairePage=$event.value; - this.openaireResults=[]; - this.searchOpenaire(this.keyword,10,this.openairePage); - this.warningMessage = ""; - this.infoMessage = ""; - - } - isSelected(id:string){ - - var found:boolean = false; - this.warningMessage = ""; - for (var _i = 0; _i < this.selectedDatasets.length; _i++) { - let item = this.selectedDatasets[_i]; - if(item.id == id){ - found=true; - break; - } - } - return found; - } -} diff --git a/portal-2/src/app/claims/claim-utils/claimProject.component.ts b/portal-2/src/app/claims/claim-utils/claimProjectSearchForm.component.ts similarity index 83% rename from portal-2/src/app/claims/claim-utils/claimProject.component.ts rename to portal-2/src/app/claims/claim-utils/claimProjectSearchForm.component.ts index fe79c86e..4a305a70 100644 --- a/portal-2/src/app/claims/claim-utils/claimProject.component.ts +++ b/portal-2/src/app/claims/claim-utils/claimProjectSearchForm.component.ts @@ -7,46 +7,47 @@ import { Subject } from 'rxjs/Subject'; import {ClaimProject} from './claimEntities.class'; declare var UIkit:any; @Component({ - selector: 'claim-projects', + selector: 'claim-projects-search-form', // styleUrls: ['/autoComplete.component.css'], template: ` -
-
-
- + +
+ Search for projects: + + - +
- - - - - - + + + ` }) -export class ClaimProjectsComponent { +export class ClaimProjectsSearchFormComponent { ngOnInit() { this.getFunders(); } @ViewChild (ModalLoading) loading : ModalLoading ; - @Input() public inline: boolean = false ; // for claimed started from landing pages + // @Input() public inline: boolean = false ; // for claimed started from landing pages public query = ''; @Input() public selectedProjects=[] ; public elementRef; public funders:string[]; - @Input() public selectedFunderId:string ="0"; + public selectedFunderId:string ="0"; selectedFunderName:string ="Select funder:"; - @Output() cselectedFunderChange = new EventEmitter(); + @Output() projectSelected = new EventEmitter(); public projects:string[]; public warningMessage = ""; @@ -116,6 +117,9 @@ select(item){ if (!found) { this.selectedProjects.push(project); + this.projectSelected.emit({ + value: true + }); UIkit.notify({ message : 'A project "'+item.projectName+'" is selected.', status : 'info', diff --git a/portal-2/src/app/claims/claim-utils/claimProject.module.ts b/portal-2/src/app/claims/claim-utils/claimProjectSearchForm.module.ts similarity index 76% rename from portal-2/src/app/claims/claim-utils/claimProject.module.ts rename to portal-2/src/app/claims/claim-utils/claimProjectSearchForm.module.ts index 0a26efff..ab5c00bb 100644 --- a/portal-2/src/app/claims/claim-utils/claimProject.module.ts +++ b/portal-2/src/app/claims/claim-utils/claimProjectSearchForm.module.ts @@ -3,7 +3,7 @@ import { NgModule } from '@angular/core'; import { SharedModule } from '../../shared/shared.module'; import { CommonModule } from '@angular/common'; -import {ClaimProjectsComponent} from './claimProject.component'; +import {ClaimProjectsSearchFormComponent} from './claimProjectSearchForm.component'; import {LoadingModalModule} from '../../utils/modal/loadingModal.module'; import {ProjectServiceModule} from '../../landingPages/project/projectService.module'; @@ -17,9 +17,9 @@ import {EntitiesAutocompleteModule} from '../../utils/entitiesAutoComplete/entit providers:[ ], declarations: [ - ClaimProjectsComponent + ClaimProjectsSearchFormComponent ], - exports: [ClaimProjectsComponent ] + exports: [ClaimProjectsSearchFormComponent ] }) -export class ClaimProjectModule { } +export class ClaimProjectsSearchFormModule { } diff --git a/portal-2/src/app/claims/claim-utils/claimPublication.component.html b/portal-2/src/app/claims/claim-utils/claimPublication.component.html deleted file mode 100644 index 8c1474d3..00000000 --- a/portal-2/src/app/claims/claim-utils/claimPublication.component.html +++ /dev/null @@ -1,121 +0,0 @@ - -
- - - -
    -
  • -
    - - - - -
    -
    - -
    -
    -
    -
      -
    • -
      - {{item.title}} - {{item.title}} - -
      - - - - -
    • -
    -
    -
    -
  • -
  • -
    - - - - -
    -
    - -
    -
    -
    -
      -
    • -
      - {{result['title'].name}} - {{result['title'].name}} - -
      - - - -
    • -
    -
    -
    -
  • -
  • -
    - - - -
    No results found
    - -
    -
    Not the right author? Choose one of these: - - - - - - - -
    - Results for - {{authorGivenName}} {{authorFamilyName}} - {{authorId}} : - - -
    -
    - -
    - -
    -
    -
      -
    • -
      - {{item['work-title']['title'].value}} - -
      - - - -
    • -
    -
    No results found
    -
    -
    -
    -
  • -
-
diff --git a/portal-2/src/app/claims/claim-utils/claimPublication.component.ts b/portal-2/src/app/claims/claim-utils/claimPublication.component.ts deleted file mode 100644 index 4e7428f4..00000000 --- a/portal-2/src/app/claims/claim-utils/claimPublication.component.ts +++ /dev/null @@ -1,401 +0,0 @@ -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 { ErrorCodes} from '../../utils/properties/openaireProperties'; -import {ClaimResult} from '../claim-utils/claimEntities.class'; -import{DOI} from '../../utils/string-utils.class'; - -@Component({ - selector: 'claim-publication', - templateUrl: 'claimPublication.component.html', - -}) -export class ClaimPublicationComponent { - constructor (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)+ "-01-01" ; - - } - ngOnInit() { - this.sub = this.route.params.subscribe(params => { - if(this.keyword !=null && this.keyword.length > 0){ - this.search(this.keyword); - } - }); - -} -ngOnDestroy() { - this.sub.unsubscribe(); -} -@Input() public keyword:string = ""; -@Input() public select:boolean = true ; -@Input() public selectedPublications = [] ; -@Output() publicationsChange = new EventEmitter(); - sub: any; - size:number = 10; - source: string = "crossref"; - type : string = "publication"; - errorCodes:ErrorCodes = new ErrorCodes(); - - crossrefResults=[]; - crossrefResultsNum : number = null; - crossrefPage : number = 1; - crossrefStatus:number = this.errorCodes.NONE; - - openaireResults = []; - openaireResultsNum: number ; - openairePage : number = 1; - openaireStatus:number = this.errorCodes.NONE; - - orcidResults: string[]; - orcidResultsNum: number ; - totalPages: number; - orcidResultsToShow: string[]; - orcidPage : number = 1; - orcidStatus:number = this.errorCodes.NONE; - authorId: string; - authorGivenName: string; - authorFamilyName: string; - - authorIds: string[]; - authorGivenNames: string[]; - authorFamilyNames: string[]; - - authorsNum : number ; - - public warningMessage = ""; - public infoMessage = ""; - - todayDate = ''; - nextDate = ''; -private DOIs:string[] = []; - -public search(term: string){ - this.warningMessage = ""; - this.infoMessage = ""; - this.DOIs = DOI.getDOIsFromString(term); - this.getCrossrefResults(term, this.size,1); - this.searchOrcid(term); - this.searchOpenaire(term, this.size, 1); -} - - -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 searchOpenaire(term: string, size : number, page : number) { - - if(this.DOIs.length > 0 ){ - this.openaireStatus = this.errorCodes.LOADING; - this._searchPublicationsService.searchPublicationsByDois(this.DOIs, null, page, size, []).subscribe( - data => { - if(data != null) { - this.openairePage=page; - this.openaireResultsNum = data[0]; - this.openaireResults = data[1]; - this.openaireStatus = this.errorCodes.DONE; - if(this.openaireResultsNum == 0){ - this.openaireStatus = this.errorCodes.NONE; - } - }else { - this.openaireStatus = this.errorCodes.ERROR; - } - }, - err => { - this.openaireStatus = this.errorCodes.ERROR; - console.log(err.status); - } - ); - }else{ - this.openaireStatus = this.errorCodes.LOADING; - this._searchPublicationsService.searchPublications('q='+term, null, page, size, []).subscribe( - data => { - if(data != null) { - this.openairePage=page; - this.openaireResultsNum = data[0]; - this.openaireResults = data[1]; - this.openaireStatus = this.errorCodes.DONE; - if(this.openaireResultsNum == 0){ - this.openaireStatus = this.errorCodes.NONE; - } - }else { - this.openaireStatus = this.errorCodes.ERROR; - } - }, - err => { - this.openaireStatus = 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.getOrcidResultsById(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; - - //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.getOrcidResultsById(0); - }else{ - this.orcidStatus = this.errorCodes.ERROR; - } - - }, - err => { - this.orcidStatus = this.errorCodes.ERROR; - console.log(err.status); - } - ); - } - - - private getOrcidResultsById (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.authorId = id; - console.info("getOrcidResultsById: "+id); - 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; - } - ); - - } - } - private add(item, id, itemSource, itemType, itemUrl, itemTitle, date, accessMode){ - var result: ClaimResult ; - if(itemSource == 'crossref'){ - date = (date == null) ? null : date.substring(0,10); - result = {id: id, 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 = {id:id, 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:id, type :itemType, source : itemSource, title: itemTitle,url: itemUrl, result: item, accessRights: accessMode, embargoEndDate: null, date: date}; - - } - console.info("Added result:"+result.date); - var found:boolean = this.isSelected(result.id); - this.warningMessage = ""; - if (!found) { - this.selectedPublications.push(result); - this.publicationsChange.emit({ - value: this.selectedPublications - }); - }else{ - this.warningMessage = "Publication already in selected list"; - } - - } - private remove(item){ - this.warningMessage = ""; - this.infoMessage = ""; - var index:number =this.selectedPublications.indexOf(item); - item.selected=false; - if (index > -1) { - this.selectedPublications.splice(index, 1); - this.publicationsChange.emit({ - value: this.selectedPublications - }); - } - - } -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 openairePageChange($event) { - this.openairePage=$event.value; - this.searchOpenaire(this.keyword,this.size,this.openairePage); -} - - private isSelected(id:string){ - - var found:boolean = false; - this.warningMessage = ""; - for (var _i = 0; _i < this.selectedPublications.length; _i++) { - let item = this.selectedPublications[_i]; - if(item.id == id){ - found=true; - this.warningMessage = "Publication already in selected list"; - } - } - return found; - - - } -} diff --git a/portal-2/src/app/claims/claim-utils/claimResult.component.ts b/portal-2/src/app/claims/claim-utils/claimResult.component.ts deleted file mode 100644 index 737c4539..00000000 --- a/portal-2/src/app/claims/claim-utils/claimResult.component.ts +++ /dev/null @@ -1,107 +0,0 @@ -import {Component, Input, Output, EventEmitter, ViewChild} from '@angular/core'; -import {ClaimPublicationComponent} from './claimPublication.component'; -import {ClaimDatasetComponent} from './claimDataset.component'; - -@Component({ - selector: 'claim-result', - template: ` - - -
-
-
- - -
- - - - - - - - - - - -
-
-
-
-
-
- -
-
- -
-
- - `, -}) -export class ClaimResultComponent { - constructor () { - 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.searchDatacite(this.keyword,this.size,this.page); - // } -} - @ViewChild (ClaimPublicationComponent) claimPublicationComponent : ClaimPublicationComponent ; - @ViewChild (ClaimDatasetComponent) claimDatasetComponent : ClaimDatasetComponent ; - - page : number = 1; - size:number = 10; - navigateTo: string = "Search"; - source: string = "datacite"; - type : string = "dataset"; - searchType ="publication"; - @Input() public select:boolean = true ; - @Input() public keyword:string = ''; - @Input() public selectedDatasets = [] ; - @Input() public selectedPublications = [] ; - @Output() datasetsChange = new EventEmitter(); - @Output() publicationsChange = new EventEmitter(); - - todayDate = ''; - nextDate = ''; - search(){ - if(this.searchType=='dataset'){ - this.claimDatasetComponent.search(this.keyword,10,1); - }else{ - this.claimPublicationComponent.search(this.keyword); - } - } - - typeChanged(type:string) { - this.searchType = type; - } - publicationsChanged($event) { - this.selectedPublications=$event.value; - this.publicationsChange.emit({ - value: this.selectedPublications - }); - - } - datasetsChanged($event) { - this.selectedDatasets=$event.value; - this.datasetsChange.emit({ - value: this.selectedDatasets - }); - } -} diff --git a/portal-2/src/app/claims/claim-utils/claimResultSearchForm.component.html b/portal-2/src/app/claims/claim-utils/claimResultSearchForm.component.html new file mode 100644 index 00000000..f89ac42a --- /dev/null +++ b/portal-2/src/app/claims/claim-utils/claimResultSearchForm.component.html @@ -0,0 +1,182 @@ +
+
+ + + + +
+
+ +
+ +
    +
  • +
    + + + + +
    +
    + +
    +
    +
    +
      +
    • +
      + {{item.title}} + {{item.title}} + +
      + + + + +
    • +
    +
    +
    +
  • +
  • +
    + + + + +
    +
    + +
    +
    +
    +
      +
    • +
      + {{result['title'].name}} + {{result['title'].name}} + +
      + + + +
    • +
    +
    +
    +
  • +
  • +
    + + + +
    No results found
    + +
    +
    Not the right author? Choose one of these: + + + + + + + +
    + Results for + {{authorGivenName}} {{authorFamilyName}} - {{authorId}} : + + +
    +
    + +
    + +
    +
    +
      +
    • +
      + {{item['work-title']['title'].value}} + +
      + + + +
    • +
    +
    No results found
    +
    +
    +
    +
  • +
  • + + + + +
    +
    +
    + +
    +
    + +
    +
      +
    • +
      + {{item.title}} + {{item.title}} + + +
      + + + +
    • +
    + +
    +
    +
  • +
  • + + + + +
    +
    +
    + +
    +
    +
    +
      +
    • +
      + {{result['title'].name}} + {{result['title'].name}} + + + +
      + + + +
    • +
    + +
    +
    +
  • +
+
diff --git a/portal-2/src/app/claims/claim-utils/claimResultSearchForm.component.ts b/portal-2/src/app/claims/claim-utils/claimResultSearchForm.component.ts new file mode 100644 index 00000000..804e4a55 --- /dev/null +++ b/portal-2/src/app/claims/claim-utils/claimResultSearchForm.component.ts @@ -0,0 +1,531 @@ +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 { ErrorCodes} from '../../utils/properties/openaireProperties'; +import {ClaimResult} from '../claim-utils/claimEntities.class'; +import{DOI} from '../../utils/string-utils.class'; + +@Component({ + selector: 'claim-result-search-form', + templateUrl: 'claimResultSearchForm.component.html', + +}) +export class ClaimResultSearchFormComponent { + constructor (private _searchDataciteService: SearchDataciteService, private _searchDatasetsService:SearchDatasetsService, + 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(); + } +} + + + page : number = 1; + size:number = 10; + navigateTo: string = "Search"; + source: string = "datacite"; + type : string = "dataset"; + // searchType ="publication"; + @Input() public select:boolean = true ; + @Input() public keyword:string = ''; + @Input() public selectedResults = [] ; + // @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; + + public warningMessage = ""; + public infoMessage = ""; + + public todayDate = ''; + public nextDate = ''; + public DOIs:string[] = []; + sub: any; + + + + 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; + authorGivenName: string; + authorFamilyName: string; + + authorIds: string[]; + authorGivenNames: string[]; + authorFamilyNames: string[]; + + authorsNum : number ; + + + + search(){ + this.warningMessage = ""; + this.infoMessage = ""; + this.DOIs = DOI.getDOIsFromString(this.keyword); + this.getCrossrefResults(this.keyword, this.size,1); + this.searchOrcid(this.keyword); + this.searchOpenairePubs(this.keyword, this.size, 1); + this.searchDatacite(this.keyword,10,1); + this.searchOpenaireData(this.keyword,10,1); + + } + +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.getOrcidResultsById(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; + + //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.getOrcidResultsById(0); + }else{ + this.orcidStatus = this.errorCodes.ERROR; + } + + }, + err => { + this.orcidStatus = this.errorCodes.ERROR; + console.log(err.status); + } + ); + } + + + private getOrcidResultsById (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.authorId = id; + console.info("getOrcidResultsById: "+id); + 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 = ""; + +} + + + 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 getDataciteResults (term: string, size : number, page : number) { + this._searchDataciteService.searchDataciteResults(term, size, page).subscribe( + data => { + this.dataciteResults = data.docs; + this.datacitePage=page; + this.dataciteResultsNum = data.numFound; + 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 ; + if(itemSource == 'datacite'){ + 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}; + }else if(itemSource == 'crossref'){ + date = (date == null) ? null : date.substring(0,10); + 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 = {id:itemId, type :itemType, source : itemSource, title: itemTitle,url: itemUrl, result: item, accessRights: 'OPEN', embargoEndDate: this.nextDate, date: date}; + } + var found:boolean = this.isSelected( result.id); + + this.warningMessage = ""; + if (!found) { + this.selectedResults.push(result); + this.resultsChange.emit({ + value: this.selectedResults + }); + }else{ + this.warningMessage = "Dataset already in selected list"; + } + + } + + +Pag +} diff --git a/portal-2/src/app/claims/claim-utils/claimResult.module.ts b/portal-2/src/app/claims/claim-utils/claimResultSearchForm.module.ts similarity index 71% rename from portal-2/src/app/claims/claim-utils/claimResult.module.ts rename to portal-2/src/app/claims/claim-utils/claimResultSearchForm.module.ts index a264475d..a7874d35 100644 --- a/portal-2/src/app/claims/claim-utils/claimResult.module.ts +++ b/portal-2/src/app/claims/claim-utils/claimResultSearchForm.module.ts @@ -2,10 +2,7 @@ import { NgModule } from '@angular/core'; import { SharedModule } from '../../shared/shared.module'; import { CommonModule } from '@angular/common'; - -import {ClaimPublicationComponent} from './claimPublication.component'; -import {ClaimDatasetComponent} from './claimDataset.component'; -import {ClaimResultComponent} from './claimResult.component'; +import {ClaimResultSearchFormComponent} from './claimResultSearchForm.component'; import {SearchDataciteService} from './service/searchDatacite.service'; import {SearchCrossrefServiceModule} from './service/searchCrossrefService.module'; @@ -23,9 +20,9 @@ import {PagingModule } from '../../utils/paging.module'; SearchDataciteService, SearchOrcidService ], declarations: [ - ClaimPublicationComponent, ClaimDatasetComponent, ClaimResultComponent + ClaimResultSearchFormComponent ], - exports: [ClaimResultComponent ] + exports: [ClaimResultSearchFormComponent ] }) -export class ClaimResultModule { } +export class ClaimResultSearchFormModule { } diff --git a/portal-2/src/app/claims/claim-utils/service/claims.service.ts b/portal-2/src/app/claims/claim-utils/service/claims.service.ts index defd985d..699ddf04 100644 --- a/portal-2/src/app/claims/claim-utils/service/claims.service.ts +++ b/portal-2/src/app/claims/claim-utils/service/claims.service.ts @@ -16,10 +16,10 @@ export class ClaimsService { this.baseUrl = OpenaireProperties.getClaimsAPIURL(); } - private getClaimRequest(size : number, page : number, url :string):any { + private getClaimRequest(size : number, page : number, url :string, fromCache:boolean):any { console.info('ClaimsService: Claims request: '+url); let key = url; - if (this._cache.has(key)) { + if (fromCache && this._cache.has(key)) { return Observable.of(this._cache.get(key)); } return this.http.get( url) @@ -34,31 +34,31 @@ export class ClaimsService { 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); + 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/"+user+"/claims"+"?offset="+(size*(page-1) + "&limit="+size)+"&keyword="+keyword+"&sortby="+sortby+"&descending="+descending+"&"+types; - return this.getClaimRequest(size,page,url); + 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); + 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); + 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); + return this.getClaimRequest(size,page,url,true); } deleteClaimById(claimId:string):any{ diff --git a/portal-2/src/app/claims/directLinking/directLinking-routing.module.ts b/portal-2/src/app/claims/directLinking/directLinking-routing.module.ts new file mode 100644 index 00000000..448c437b --- /dev/null +++ b/portal-2/src/app/claims/directLinking/directLinking-routing.module.ts @@ -0,0 +1,14 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { DirectLinkingComponent } from './directLinking.component'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: DirectLinkingComponent}, + + ]) + ] +}) +export class DirectLinkingRoutingModule { } diff --git a/portal-2/src/app/claims/directLinking/directLinking.component.ts b/portal-2/src/app/claims/directLinking/directLinking.component.ts new file mode 100644 index 00000000..e8935990 --- /dev/null +++ b/portal-2/src/app/claims/directLinking/directLinking.component.ts @@ -0,0 +1,204 @@ +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'; + +@Component({ + selector: 'directLinking', + template: ` +
+ + +
+
+ {{(type=="project")?'Project':' Research result'}}: +
+ +
+
+
+ {{displayedResult.title}} + {{displayedResult.title}} +
+ + +
+ +
+ +
+ {{projects[0].funderName}} | {{projects[0].projectName}} {{(projects[0].projectAcronym)?'('+projects[0].projectAcronym+')':''}} + +
+ + +
+ +
+ +
+
+ +
+ + + +
+
+
+ +
+
+ +
+
+ +` + +}) +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", "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) { + + } + ngOnInit() { + 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.linkTo == "publication" || this.linkTo == "dataset") || 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,isInlineResult); + }else if(this.type == "dataset"){ + this.getDatasetById(this.id,isInlineResult); + }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"].indexOf(this.type) != -1 && (["project","context","result"].indexOf(this.linkTo) == -1)){ + return false; + }else if(["project","dataset","publication"].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 = { funderId: item.funderId,funderName: item.funderName, projectId: id, projectName: item.projectName , projectAcronym: item.projectAcronym, startDate: item.startDate, endDate: item.endDate }; + 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 = {id: id, type :"publication", source : "openaire", title: item['title'].name, url: item['title'].url, result: item, accessRights:item['title'].accessMode, embargoEndDate: null, 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 = {id: id, type : "dataset", source : "openaire", title: item['title'].name, url: item['title'].url, result: item, accessRights:item['title'].accessMode, embargoEndDate: null, 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") + }); + + } + + + + resultsChange($event) { + this.results=$event.value; + } + + projectsChange($event) { + this.projects=$event.value; + } + + + + +} diff --git a/portal-2/src/app/claims/directLinking/directLinking.module.ts b/portal-2/src/app/claims/directLinking/directLinking.module.ts new file mode 100644 index 00000000..16c17e2a --- /dev/null +++ b/portal-2/src/app/claims/directLinking/directLinking.module.ts @@ -0,0 +1,30 @@ +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 {EntitySearchServiceModule} from '../../utils/entitiesAutoComplete/entitySearchService.module'; +import {PublicationsServiceModule} from '../../services/publicationsService.module'; +import {DatasetsServiceModule} from '../../services/datasetsService.module'; + + + +@NgModule({ + imports: [ + SharedModule, + DirectLinkingRoutingModule,SelectedProjectsModule, SelectedContextsModule, SelectedPublicationsModule, InsertClaimsModule, + EntitySearchServiceModule, PublicationsServiceModule, DatasetsServiceModule + + + ], + declarations: [ + DirectLinkingComponent + ], exports:[DirectLinkingComponent] +}) +export class DirectLinkingModule { } diff --git a/portal-2/src/app/claims/inlineClaims/inlineClaimContext.component.ts b/portal-2/src/app/claims/inlineClaims/inlineClaimContext.component.ts deleted file mode 100644 index f0f5cf93..00000000 --- a/portal-2/src/app/claims/inlineClaims/inlineClaimContext.component.ts +++ /dev/null @@ -1,94 +0,0 @@ -import {Component, Input, ViewChild, Output, EventEmitter} from '@angular/core'; -import {ClaimInsertComponent} from '../linking/insertClaim/insertClaim.component'; - -@Component({ - selector: 'inline-claim-context', - template: ` - - -
-
- - - -
- - - - -
-` - -}) - export class InlineClaimContextComponent { - constructor ( ) { - - } - - @Input() public inlineEntity:any; - @Input() public inlineType:string; - - - contexts=[]; - publications; - datasets; - public show = 'context'; - public showComp:boolean = false; - public enableButton:boolean=true; - public keyword: string = ""; - - @Output() contextAdded = new EventEmitter(); - -@ViewChild (ClaimInsertComponent) claimInsert : ClaimInsertComponent ; - ngOnInit() { - - } - showChange($event) { - this.show=$event.value; - if(this.show == "end"){ - //TODO - this.contextAdded.emit({ - value: this.contexts - }); - this.contexts = []; - this.showComponent(); - - }else if(this.show == "error"){ - this.showComponent(); - } - } - public toggle(){ - if(!this.showComp){ - this.showComponent(); - }else{ - this.hideComponent(); - } - } - private showComponent(){ - this.showComp=true; - this.enableButton = true; - - } - private hideComponent(){ - this.showComp=false; - } - private insert(){ - this.claimInsert.publications = []; - this.claimInsert.publications.push(this.inlineEntity); - this.publications = []; - this.publications.push(this.inlineEntity); - console.info(" result: :targetId: " +this.publications[0].id + "targetType :"+ this.publications[0].type+" targetCollectedFrom:"+ this.publications[0].source+ "targetAccessRights :"+this.publications[0].accessRights+ " targetEmbargoEndDate:"+this.publications[0].embargoEndDate); - this.enableButton = false; - if (!this.claimInsert.validateInsertions()){ - this.enableButton = true; - } - - - } - private cancel(){ - this.contexts = []; - - this.hideComponent(); - } -} diff --git a/portal-2/src/app/claims/inlineClaims/inlineClaimProject.component.ts b/portal-2/src/app/claims/inlineClaims/inlineClaimProject.component.ts deleted file mode 100644 index 4f8cd392..00000000 --- a/portal-2/src/app/claims/inlineClaims/inlineClaimProject.component.ts +++ /dev/null @@ -1,107 +0,0 @@ -import {Component, Input, ViewChild, Output, EventEmitter} from '@angular/core'; -import {Observable} from 'rxjs/Observable'; -import {ClaimInsertComponent} from '../linking/insertClaim/insertClaim.component'; - -@Component({ - selector: 'inline-claim-project', - template: ` - - -
-
- - - -
- - - -
- - - -` - -}) - export class InlineClaimProjectComponent { - constructor () { - - } - - @Input() public inlineEntity:any; - @Input() public inlineType:string; - - - public projects=[]; - public publications; - public datasets; - public show = 'project'; - public showComp:boolean = false; - public enableButton:boolean=true; - public keyword: string = ""; - - @Output() projectAdded = new EventEmitter(); - -@ViewChild (ClaimInsertComponent) claimInsert : ClaimInsertComponent ; - ngOnInit() { - - } - - showChange($event) { - this.show=$event.value; - if(this.show == "end"){ - //TODO - this.projectAdded.emit({ - value: this.projects - }); - this.projects = []; - this.showComponent(); - }else if(this.show == "error"){ - this.showComponent(); - } - } - public toggle(){ - console.info("TOOGLE pr "); - if(!this.showComp){ - console.info("TOOGLE show "); - this.showComponent(); - }else{ - console.info("TOOGLE hide "); - this.hideComponent(); - } - } - private showComponent(){ - this.showComp=true; - this.enableButton = true; - - } - private hideComponent(){ - this.showComp=false; - } - private insert(){ - if(this.inlineType === 'dataset'){ - this.datasets = []; - this.datasets.push(this.inlineEntity); - this.claimInsert.datasets = []; - this.claimInsert.datasets.push(this.inlineEntity); - }else if(this.inlineType === 'publication'){ - this.claimInsert.publications = []; - this.claimInsert.publications.push(this.inlineEntity); - this.publications = []; - this.publications.push(this.inlineEntity); - console.info(" result: :targetId: " +this.publications[0].id + "targetType :"+ this.publications[0].type+" targetCollectedFrom:"+ this.publications[0].source+ "targetAccessRights :"+this.publications[0].accessRights+ " targetEmbargoEndDate:"+this.publications[0].embargoEndDate); - } - this.enableButton = false; - if (!this.claimInsert.validateInsertions()){ - this.enableButton = true; - } - - - } - private cancel(){ - this.projects = []; - - this.hideComponent(); - } -} diff --git a/portal-2/src/app/claims/inlineClaims/inlineClaimResult.component.ts b/portal-2/src/app/claims/inlineClaims/inlineClaimResult.component.ts deleted file mode 100644 index cc14b9c7..00000000 --- a/portal-2/src/app/claims/inlineClaims/inlineClaimResult.component.ts +++ /dev/null @@ -1,117 +0,0 @@ -import {Component, Input, ViewChild, Output, EventEmitter} from '@angular/core'; -import {Observable} from 'rxjs/Observable'; -import {ClaimInsertComponent} from '../linking/insertClaim/insertClaim.component'; -// import {ClaimResultComponent} from '../linking/claimResult/claimResult.component'; -// import {ClaimSelectedResultsComponent} from '../linking/selected/selectedResults.component'; - -@Component({ - selector: 'inline-claim-result', - template: ` - - -
-
- - - - -
- - - -
- - - -` - -}) - export class InlineClaimResultComponent { - constructor () { - - } - // This is the component from the landing page - @Input() public inlineEntity:any; - @Input() public inlineType:string; - public hideType:string; - - - - public publications = []; - public datasets = []; - public show = 'project'; - public showComp:boolean = false; - public enableButton:boolean=true; - public keyword: string = ""; - -@Output() datasetAdded = new EventEmitter(); -@Output() publicationAdded = new EventEmitter(); - -@ViewChild (ClaimInsertComponent) claimInsert : ClaimInsertComponent ; - ngOnInit() { - console.info("Inline entity:"+this.inlineEntity.id); - this.hideType = this.inlineType; - if(this.inlineType == 'dataset' || this.inlineType == 'publication' ){ - this.hideType = ""; - } - } - - datasetsChange($event) { - this.datasets=$event.value; - console.log($event.value); - } - publicationsChange($event) { - this.publications=$event.value; - console.log($event.value); - } - showChange($event) { - this.show=$event.value; - if(this.show == "end"){ - this.datasetAdded.emit({ - value: this.datasets - }); - this.publicationAdded.emit({ - value: this.publications - }); - this.datasets = []; - this.publications = []; - this.showComponent(); - }else if(this.show == "error"){ - this.showComponent(); - } - } - public toggle(){ - if(!this.showComp){ - this.showComponent(); - }else{ - this.hideComponent(); - } - } - private showComponent(){ - this.showComp=true; - this.enableButton = true; - - } - private hideComponent(){ - this.showComp=false; - } - private insert(){ - if(this.inlineType === 'project'){ //TODO check if neccessary - this.claimInsert.projects = []; - this.claimInsert.projects.push(this.inlineEntity); - } - - this.enableButton = false; - if (!this.claimInsert.validateInsertions()){ - this.enableButton = true; - } - - } - private cancel(){ - this.datasets = []; - this.publications = []; - this.hideComponent(); - } -} diff --git a/portal-2/src/app/claims/linking/insertClaim/insertClaim.component.ts b/portal-2/src/app/claims/linking/insertClaim/insertClaim.component.ts index 75c6ef29..98f8f431 100644 --- a/portal-2/src/app/claims/linking/insertClaim/insertClaim.component.ts +++ b/portal-2/src/app/claims/linking/insertClaim/insertClaim.component.ts @@ -31,12 +31,10 @@ export class ClaimInsertComponent { @Input() public contexts; @Input() public projects; - @Input() public publications; - @Input() public datasets; + @Input() public results; @Input() public showButton:boolean = true; @Input() show='claim'; - @Input() inline: boolean = false; // link from landing page? - @Input() inlineEntity; // the entity from the landing page + @Input() inlineEntity = null; // the entity from the landing page @Output() showChange = new EventEmitter(); @ViewChild (ModalLoading) loading : ModalLoading ; @@ -65,12 +63,12 @@ private insert(){ var user="argirok@di.uoa.gr" this.loading.open(); var claims = []; - if(this.publications){ - console.info("publications: "+this.publications.length); + if(this.results){ + console.info("results: "+this.results.length); - for (var i = 0; i < this.publications.length; i++) { + for (var i = 0; i < this.results.length; i++) { - var result=this.publications[i]; + var result=this.results[i]; if(this.contexts){ for (var j = 0; j < this.contexts.length; j++) { var context = this.contexts[j]; @@ -85,37 +83,14 @@ private insert(){ claims.push(projectClaim); } } - if(this.inline && this.inlineEntity){ + if(this.inlineEntity != null){ var resultClaim = this.createResultClaim(this.inlineEntity, result, user); claims.push(resultClaim); } } } - if(this.datasets){ - for (var i = 0; i < this.datasets.length; i++) { - var result=this.datasets[i]; - 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.inline && this.inlineEntity){ - var resultClaim = this.createResultClaim(this.inlineEntity, result, user); - claims.push(resultClaim); - } - } - } console.info("try to insert "+claims.length+" claims"); this.claimService.insertBulkClaims(claims).subscribe( data => { @@ -133,9 +108,9 @@ private insert(){ private validate(){ this.warningMessage = ""; this.errorMessage = ""; - if(this.datasets && this.datasets.length == 0 && this.publications && this.publications.length == 0){ - this.warningMessage = "There are no publications or datasets selected."; - }else if((!this.contexts|| this.contexts.length==0 )&&(!this.projects|| this.projects.length==0 )&& ( !this.inlineEntity)){ + 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 concepts to link."; // }else if (this.inline && !this.inlineEntity){ // this.errorMessage = "No inline entity"; @@ -150,21 +125,9 @@ private validateDates(){ for (var k = 0; k < this.projects.length; k++) { var project = this.projects[k]; console.info(project.startDate+" "+project.endDate + " "+project.projectAcronym); - if(this.publications){ - for (var i = 0; i < this.publications.length; i++) { - var result = this.publications[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) ){ - this.confirmOpen(); - return false; - } - } - } - } - if(this.datasets){ - for (var i = 0; i < this.datasets.length; i++) { - var result = this.datasets[i]; + 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) ){ @@ -178,9 +141,9 @@ private validateDates(){ } } - if(this.publications){ - for (var i = 0; i < this.publications.length; i++) { - var result = this.publications[i]; + 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 ){ @@ -190,28 +153,17 @@ private validateDates(){ } } } - if(this.datasets){ - for (var i = 0; i < this.datasets.length; i++) { - var result = this.datasets[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(insertedIds, errorInClaims){ this.loading.close(); if(errorInClaims.length == 0 && insertedIds.length > 0 ){ - if(this.inline){ - this.show = "end"; - }else{ + // if(this.inline){ + // this.show = "end"; + // }else{ this._router.navigate( ['/myclaims'] ); - } + // } this.showChange.emit({ value: this.show }); @@ -223,12 +175,12 @@ private errorsInClaimsInsertion(insertedIds, errorInClaims){ this.errorMessage = "An Error Occured."; this.loading.close(); this.error = true; - if(this.inline){ - this.show = "error"; - this.showChange.emit({ - value: this.show - }); - } + // if(this.inline){ + // this.show = "error"; + // this.showChange.emit({ + // value: this.show + // }); + // } } diff --git a/portal-2/src/app/claims/linking/linkingGeneric.component.ts b/portal-2/src/app/claims/linking/linkingGeneric.component.ts index bdf09d93..6ae89c09 100644 --- a/portal-2/src/app/claims/linking/linkingGeneric.component.ts +++ b/portal-2/src/app/claims/linking/linkingGeneric.component.ts @@ -12,9 +12,9 @@ import {SearchDatasetsService} from '../../services/searchDatasets.service';
@@ -28,71 +28,36 @@ import {SearchDatasetsService} from '../../services/searchDatasets.service';
  • Upload & LinkUpload & Link
  • -
    -
    - -
    -
    - -
    -
    -

    TODO software

    -
    -
    - + + +
    + +
    + -
    -
    - +
    +
    +
    -
    - +
    +
    - -
    - - -
    -
    - -
    -
    -
    +
    - -
    - -
    -
    - -
    - - -
    - - -
    -
    - - -
    -
    -
    @@ -109,144 +74,61 @@ export class LinkingGenericComponent { step:number = 1; contexts=[]; projects=[]; - publications=[]; - datasets=[]; + results = []; show = "home"; date='8-6-2016'; keyword: string = ""; linkType:string ="project"; // link type (selected in home page) : project, context, software, etc - /* Parameters for inline linking */ + /* 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) + linkTo:string = null; // entity type (project or context or result) + entityTypes=["dataset", "publication", "project","context"]; - inlineSearchResult:ClaimResult =null; + inlineResult:ClaimResult =null; sub:any =null; constructor ( private _router: Router, private route: ActivatedRoute, private entitySearch:EntitiesSearchService, private publicationsSearch:SearchPublicationsService, private datasetsSearch:SearchDatasetsService) { } ngOnInit() { - 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; - this.linkType = this.linkTo; - var isInlineSearchResult:boolean = false; - if((this.type == "publication" || this.type == "dataset") && (this.linkTo == "publication" || this.linkTo == "dataset")){ - isInlineSearchResult = true; - } - if(this.type == "project"){ - this.linkType = "project"; - this.getProjectById(this.id); - }else if(this.type == "publication"){ - this.getPublicationById(this.id,isInlineSearchResult); - }else if(this.type == "dataset"){ - this.getDatasetById(this.id,isInlineSearchResult); - } - - } - - }); } - getProjectById(id:string){ - this.sub = this.entitySearch.fetchByType(id,"project").subscribe( - data => { - console.log(data); - var item =data[0]; - var project: ClaimProject = { funderId: item.funderId,funderName: item.funderName, projectId: id, projectName: item.projectName , projectAcronym: item.projectAcronym, startDate: item.startDate, endDate: item.endDate }; - this.projects.push( project); - - }, - err => console.log("An error occured")); - } - getPublicationById(id:string, isInlineSearchResult:boolean){ - - this.sub = this.publicationsSearch.searchPublicationById(id).subscribe( - data => { - var item =data[0]; - - var result: ClaimResult = {id: id, type :"publication", source : "openaire", title: item['title'].name, url: item['title'].url, result: item, accessRights:item['title'].accessMode, embargoEndDate: null, date: item.year}; - if(isInlineSearchResult){ - this.inlineSearchResult = result; - }else{ - this.publications.push( result); - } - }, - err => console.log("An error occured")); - } - getDatasetById(id:string, isInlineSearchResult:boolean){ - this.sub = this.datasetsSearch.searchDatasetById(id).subscribe( - data => { - var item =data[0]; - console.log(item); - var result: ClaimResult = {id: id, type : "dataset", source : "openaire", title: item['title'].name, url: item['title'].url, result: item, accessRights:item['title'].accessMode, embargoEndDate: null, date: item.year}; - if(isInlineSearchResult){ - this.inlineSearchResult = result; - }else{ - this.datasets.push( result); - } - }, - err => console.log("An error occured")); - - } next(){ - if((this.show == 'project' || this.show == 'context' || this.show == 'software')){ - if(!this.bulkMode){ - this.show='result'; - }else{ - this.show='claim'; - } - }else if((this.show == 'result' && this.keyword == '')||(this.show == 'dataset' || this.show == 'publication')){ + if((this.show == 'result' && this.keyword == '')||(this.show == 'dataset' || this.show == 'publication')){ this.show='claim'; } } prev(){ if(this.show == 'result'){ - this.show = this.linkType; - }else if(this.show == 'context' || this.show == 'project' || this.show == 'software' ){ - this.show='home'; - } else if(this.show == 'claim'){ + this.show = 'home'//this.linkType; + + } else if(this.show == 'claim'){ if(!this.bulkMode){ this.show='result'; }else{ - this.show = this.linkType; + this.show = "home"; } } } - goto(term: string) { - this._router.navigate( ['Search', { keyword: term }] ); + + + resultsChange($event) { + this.results=$event.value; } - - sourceTypeChange($event) { - this.sourceType=$event.value; - console.log($event.value); - } - targetTypeChange($event) { - this.targetType=$event.value; - console.log($event.value); - } - - publicationsChange($event) { - this.publications=$event.value; - } - datasetsChange($event) { - this.datasets=$event.value; - } projectsChange($event) { this.projects=$event.value; } linkTypeChange($event) { + this.linkType =$event.value; - this.show=$event.value; + this.show="result"; + if(this.bulkMode){ + this.show="claim"; + } } showChange($event) { diff --git a/portal-2/src/app/claims/linking/linkingGeneric.module.ts b/portal-2/src/app/claims/linking/linkingGeneric.module.ts index 4872087f..45ec05ff 100644 --- a/portal-2/src/app/claims/linking/linkingGeneric.module.ts +++ b/portal-2/src/app/claims/linking/linkingGeneric.module.ts @@ -3,13 +3,7 @@ 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/selectedPublications.module'; -import {SelectedDatasetsModule} from './selected/selectedDatasets.module'; -// import {SelectedModule} from './selected/selectedResults.module'; - -import {ClaimProjectModule} from '../claim-utils/claimProject.module'; -import {ClaimResultModule} from '../claim-utils/claimResult.module'; -import {ClaimContextModule} from '../claim-utils/claimContext.module'; +import {SelectedPublicationsModule} from './selected/selectedResults.module'; import {InsertClaimsModule} from './insertClaim/insertClaim.module'; import {BulkClaimModule} from './bulkClaim/bulkClaim.module'; @@ -23,8 +17,8 @@ import {DatasetsServiceModule} from '../../services/datasetsService.module'; @NgModule({ imports: [ SharedModule, SelectedProjectsModule, SelectedContextsModule, - SelectedPublicationsModule, SelectedDatasetsModule, - ClaimProjectModule, ClaimResultModule, ClaimContextModule, InsertClaimsModule, BulkClaimModule, + SelectedPublicationsModule, + InsertClaimsModule, BulkClaimModule, EntitySearchServiceModule, PublicationsServiceModule, DatasetsServiceModule ], declarations: [ diff --git a/portal-2/src/app/claims/linking/linkingHome.component.ts b/portal-2/src/app/claims/linking/linkingHome.component.ts index 5c8348ae..fff9d4cc 100644 --- a/portal-2/src/app/claims/linking/linkingHome.component.ts +++ b/portal-2/src/app/claims/linking/linkingHome.component.ts @@ -8,19 +8,13 @@ import {Observable} from 'rxjs/Observable';
    - - +
    +
    + Bulk mode linking +

    Link Research Results to projects & communities, providing a CSV file with research results' DOIs

    + +
    +
    +
    +
    + Linking +

    Search for Research Results and link them to projects & communities

    + +
    +
    diff --git a/portal-2/src/app/claims/linking/selected/selectedContexts.component.ts b/portal-2/src/app/claims/linking/selected/selectedContexts.component.ts index 075216b4..cdbf14b9 100644 --- a/portal-2/src/app/claims/linking/selected/selectedContexts.component.ts +++ b/portal-2/src/app/claims/linking/selected/selectedContexts.component.ts @@ -3,14 +3,14 @@ import {ClaimContext} from '../../claim-utils/claimEntities.class'; @Component({ selector: 'claim-selected-contexts', template: ` -
    + - -
    -

    Concepts ({{(contexts.length)}}) - -

    + +
    +

    to link with Communities ({{(contexts.length)}})

    +
    +
    • {{context.community }} > {{context.category}} > {{context.concept.label}} @@ -21,9 +21,24 @@ import {ClaimContext} from '../../claim-utils/claimEntities.class'; There are no contexts
    +
    +

    Concepts ({{(contexts.length)}})

    +
    +
    + +
      +
    • + {{context.community }} > {{context.category}} > {{context.concept.label}} + -
    - ` + + +
    There are no communities to link with.
    +
    +
    + + + ` }) export class ClaimSelectedContextsComponent { ngOnInit() { @@ -31,16 +46,23 @@ export class ClaimSelectedContextsComponent { 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[]; @Input() componentClass:string = ""; //"" or "col-sm-6" for horizontal display (besides projects) @Input() show='home'; - @Input() inline:boolean = false; + @Input() linkType:string = "project"; + @Input() hideType; @Input() bulkMode:boolean = false; @Output() showChange = new EventEmitter(); + showsearch:boolean = false; todayDate = ''; nextDate = ''; @@ -59,8 +81,11 @@ export class ClaimSelectedContextsComponent { var index:number =this.contexts.indexOf(item); if (index > -1) { this.contexts.splice(index, 1); - } + } + } + contextSelected($event) { + this.showsearch = false; } } diff --git a/portal-2/src/app/claims/linking/selected/selectedContexts.module.ts b/portal-2/src/app/claims/linking/selected/selectedContexts.module.ts index e9833a9c..746c5edd 100644 --- a/portal-2/src/app/claims/linking/selected/selectedContexts.module.ts +++ b/portal-2/src/app/claims/linking/selected/selectedContexts.module.ts @@ -2,9 +2,11 @@ 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, + SharedModule, ClaimContextSearchFormModule ], declarations: [ ClaimSelectedContextsComponent diff --git a/portal-2/src/app/claims/linking/selected/selectedDatasets.component.ts b/portal-2/src/app/claims/linking/selected/selectedDatasets.component.ts deleted file mode 100644 index 0c926471..00000000 --- a/portal-2/src/app/claims/linking/selected/selectedDatasets.component.ts +++ /dev/null @@ -1,141 +0,0 @@ -import {Component, Input,Output, EventEmitter,ViewChild} from '@angular/core'; -import {AlertModal} from '../../../utils/modal/alert'; -import {ClaimResult} from '../../claim-utils/claimEntities.class'; -@Component({ - selector: 'claim-selected-datasets', - template: ` - -
    -

    Research Data ({{(datasets.length)}})

    -
    - - There are no selected research data - -
      -
    • -
      - -
      -
      - - {{dataset.title}} - {{dataset.title}} - -
      - - - - -
      -
      - - - - - - - - - -
      - -
      -
    • -
    - -
    -
    - - - - ` -}) -export class ClaimSelectedDatasetsComponent { - 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 -} - - - - - @Input() datasets: ClaimResult[]; - @Input() showAccessRights:boolean = false; - @Input() inline:boolean = false; - @Input() hideType; - @Input() bulkMode:boolean = false; - @Input() linkToResults:boolean = true; - @Output() datasetsChange = new EventEmitter(); - - todayDate = ''; - 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 - - removeDataset(item:any){ - var index:number =this.datasets.indexOf(item); - if (index > -1) { - this.datasets.splice(index, 1); - } - this.datasetsChange.emit({ - value: this.datasets - }); - } - - accessTypes = ["OPEN","CLOSED","EMBARGO","RESTRICTED"]; - - dateChanged (event:any, item:any) { - item.embargoEndDate = event.target.value ; - - this.confirmOpen(); - } - /* 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.datasets.length > 1 ){ - this.commonAccessRights = type; - if(this.commonAccessRights == "EMBARGO"){ - this.commonEmbargoEndDate = item.embargoEndDate; - } - this.confirmOpen(); - } - - } - confirmOpen(){ - this.alertApplyAll.cancelButton = true; - this.alertApplyAll.okButton = true; - this.alertApplyAll.alertTitle = "Change access rights"; - this.alertApplyAll.message = "Do you wish to apply the change to every dataset?"; - this.alertApplyAll.okButtonText = "Yes"; - this.alertApplyAll.cancelButtonText = "No"; - this.alertApplyAll.open(); - } - confirmClose(data){ - for (var i = 0; i < this.datasets.length; i++) { - if(this.datasets[i].source != 'openaire' ){ - this.datasets[i].accessRights = this.commonAccessRights; - if(this.commonAccessRights == "EMBARGO"){ - this.datasets[i].embargoEndDate = this.commonEmbargoEndDate; - } - } - } - } - -} diff --git a/portal-2/src/app/claims/linking/selected/selectedDatasets.module.ts b/portal-2/src/app/claims/linking/selected/selectedDatasets.module.ts deleted file mode 100644 index a8a72313..00000000 --- a/portal-2/src/app/claims/linking/selected/selectedDatasets.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; - -import { SharedModule } from '../../../shared/shared.module'; -import {ClaimSelectedDatasetsComponent} from './selectedDatasets.component'; -import {AlertModalModule} from '../../../utils/modal/alertModal.module'; -@NgModule({ - imports: [ - SharedModule, AlertModalModule - ], - declarations: [ - ClaimSelectedDatasetsComponent - ], exports:[ClaimSelectedDatasetsComponent] -}) -export class SelectedDatasetsModule { } diff --git a/portal-2/src/app/claims/linking/selected/selectedProjects.component.ts b/portal-2/src/app/claims/linking/selected/selectedProjects.component.ts index c5d023cf..4089035c 100644 --- a/portal-2/src/app/claims/linking/selected/selectedProjects.component.ts +++ b/portal-2/src/app/claims/linking/selected/selectedProjects.component.ts @@ -6,16 +6,14 @@ import {RouterHelper} from '../../../utils/routerHelper.class'; selector: 'claim-selected-projects', template: ` -
    -

    Projects ({{(projects.length)}}) +
    +

    to link with Projects ({{(projects.length)}})

    - +
    +
    +
    +
    +

    Projects ({{(projects.length)}}) + +

    + + +
    ` }) @@ -35,19 +50,24 @@ 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() inline:boolean = false; +@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 = ''; @@ -70,5 +90,9 @@ if(type != this.show){ }); } } +projectSelected($event) { + this.showsearch = false; +} + } diff --git a/portal-2/src/app/claims/linking/selected/selectedProjects.module.ts b/portal-2/src/app/claims/linking/selected/selectedProjects.module.ts index bdc0886c..528ee92f 100644 --- a/portal-2/src/app/claims/linking/selected/selectedProjects.module.ts +++ b/portal-2/src/app/claims/linking/selected/selectedProjects.module.ts @@ -1,11 +1,14 @@ + 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 + SharedModule, RouterModule, ClaimProjectsSearchFormModule ], declarations: [ ClaimSelectedProjectsComponent diff --git a/portal-2/src/app/claims/linking/selected/selectedPublications.component.ts b/portal-2/src/app/claims/linking/selected/selectedPublications.component.ts deleted file mode 100644 index 82b7cd10..00000000 --- a/portal-2/src/app/claims/linking/selected/selectedPublications.component.ts +++ /dev/null @@ -1,148 +0,0 @@ -import {Component, Input,Output, EventEmitter, ViewChild} from '@angular/core'; -import {AlertModal} from '../../../utils/modal/alert'; -import {ClaimResult} from '../../claim-utils/claimEntities.class'; - -@Component({ - selector: 'claim-selected-publications', - template: ` -
    -
    -

    Publications ({{(publications.length)}})

    -
    - There are no selected publications - -
      -
    • -
      -
      -
      - - {{pub.title}} - {{pub.title}} - -
      - - - - - - - - - - - - - -
      -
      - - - - - - -
      -
      - - - -
      -
      -
    • -
    - - -
    -
    - - ` - -}) -export class ClaimSelectedPublicationsComponent { - 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 -} - - @Input() publications: ClaimResult[]; - @Input() showAccessRights:boolean = false; - @Input() inline:boolean = false; - @Input() hideType; - @Input() bulkMode:boolean = false; - @Input() linkToResults:boolean = true; - @Output()publicationsChange = new EventEmitter(); - - @Output() showChange = new EventEmitter(); - - todayDate = ''; - 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 - - removePublication(item:any){ - var index:number =this.publications.indexOf(item); - if (index > -1) { - this.publications.splice(index, 1); - } - this.publicationsChange.emit({ - value: this.publications - }); - } - - - accessTypes = ["OPEN","CLOSED","EMBARGO","RESTRICTED"]; - - dateChanged (event:any, item:any) { - item.embargoEndDate = event.target.value ; - } - publicationsChanged($event) { - this.publications=$event.value; - this.publicationsChange.emit({ - value: this.publications - }); - } - /* 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.publications.length > 1 ){ - this.commonAccessRights = type; - if(this.commonAccessRights == "EMBARGO"){ - this.commonEmbargoEndDate = item.embargoEndDate; - } - this.confirmOpen(); - } - - } - confirmOpen(){ - this.alertApplyAll.cancelButton = true; - this.alertApplyAll.okButton = true; - this.alertApplyAll.alertTitle = "Change access rights"; - this.alertApplyAll.message = "Do you wish to apply the change to every publication?"; - this.alertApplyAll.okButtonText = "Yes"; - this.alertApplyAll.cancelButtonText = "No"; - this.alertApplyAll.open(); - } - confirmClose(data){ - for (var i = 0; i < this.publications.length; i++) { - if(this.publications[i].source != 'openaire' ){ - this.publications[i].accessRights = this.commonAccessRights; - if(this.commonAccessRights == "EMBARGO"){ - this.publications[i].embargoEndDate = this.commonEmbargoEndDate; - } - } - } - } -} diff --git a/portal-2/src/app/claims/linking/selected/selectedPublications.module.ts b/portal-2/src/app/claims/linking/selected/selectedPublications.module.ts deleted file mode 100644 index 6f8baaf3..00000000 --- a/portal-2/src/app/claims/linking/selected/selectedPublications.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; - -import { SharedModule } from '../../../shared/shared.module'; -import {ClaimSelectedPublicationsComponent} from './selectedPublications.component'; -import {AlertModalModule} from '../../../utils/modal/alertModal.module'; -@NgModule({ - imports: [ - SharedModule, AlertModalModule - ], - declarations: [ - ClaimSelectedPublicationsComponent - ], exports:[ClaimSelectedPublicationsComponent] -}) -export class SelectedPublicationsModule { } diff --git a/portal-2/src/app/claims/linking/selected/selectedResults.component.ts b/portal-2/src/app/claims/linking/selected/selectedResults.component.ts new file mode 100644 index 00000000..d6363002 --- /dev/null +++ b/portal-2/src/app/claims/linking/selected/selectedResults.component.ts @@ -0,0 +1,179 @@ +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 'mydatepicker'; +import {Dates} from '../../../utils/string-utils.class'; + +@Component({ + selector: 'claim-selected-results', + template: ` + + +
    +

    {{title}} ({{results.length}})

    +
    + +
    + +
    +
    + +
    There are no selected research results
    + +
      +
    • +
      +
      +
      + + {{pub.title}} + {{pub.title}} + +
      + + + + + + + + + + + + + + +
      +
      + + + + + + + + +
      +
      + + + + +
      +
      +
    • + +
    + + +
    +
    +
    + + ` + +}) +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 +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(); + } + + } + 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(); + } + } + + } + confirmOpen(){ + this.alertApplyAll.cancelButton = true; + this.alertApplyAll.okButton = true; + this.alertApplyAll.alertTitle = "Change access rights"; + 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){ + 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/portal-2/src/app/claims/linking/selected/selectedResults.module.ts b/portal-2/src/app/claims/linking/selected/selectedResults.module.ts index ecddb7f0..52327297 100644 --- a/portal-2/src/app/claims/linking/selected/selectedResults.module.ts +++ b/portal-2/src/app/claims/linking/selected/selectedResults.module.ts @@ -1,17 +1,17 @@ import { NgModule } from '@angular/core'; import { SharedModule } from '../../../shared/shared.module'; -import {SelectedDatasetsModule} from './selectedDatasets.module'; -import {SelectedPublicationsModule} from './selectedPublications.module'; -// import {ClaimSelectedResultsComponent} from './selectedResults.component'; +import {ClaimSelectedResultsComponent} from './selectedResults.component'; +import {AlertModalModule} from '../../../utils/modal/alertModal.module'; +import {ClaimResultSearchFormModule} from '../../claim-utils/claimResultSearchForm.module'; +import { MyDatePickerModule } from '../../../utils/my-date-picker/my-date-picker.module'; + @NgModule({ imports: [ - SharedModule, SelectedDatasetsModule, SelectedPublicationsModule + SharedModule, AlertModalModule, ClaimResultSearchFormModule, MyDatePickerModule ], declarations: [ - // ClaimSelectedResultsComponent - ], exports:[ - // ClaimSelectedResultsComponent - ] + ClaimSelectedResultsComponent + ], exports:[ClaimSelectedResultsComponent] }) -export class SelectedResultsModule { } +export class SelectedPublicationsModule { } diff --git a/portal-2/src/app/deposit/depositResult.component.ts b/portal-2/src/app/deposit/depositResult.component.ts index 360d2b66..adf484fb 100644 --- a/portal-2/src/app/deposit/depositResult.component.ts +++ b/portal-2/src/app/deposit/depositResult.component.ts @@ -45,7 +45,7 @@ import {RouterHelper} from '../utils/routerHelper.class'; - + View all {{fetchDataproviders.searchUtils.totalResults}} results @@ -197,9 +197,9 @@ export class DepositResultComponent { goToDeposit() { if(this.requestFor == "Publications") { - this._router.navigate( ['deposit-publications'] ); + this._router.navigate( ['participate/deposit-publications'] ); } else if(this.requestFor == "Research Data") { - this._router.navigate( ['deposit-datasets'] ); + this._router.navigate( ['participate/deposit-datasets'] ); } } } diff --git a/portal-2/src/app/landingPages/dataset/dataset.component.html b/portal-2/src/app/landingPages/dataset/dataset.component.html index 9971a75a..d39ea376 100644 --- a/portal-2/src/app/landingPages/dataset/dataset.component.html +++ b/portal-2/src/app/landingPages/dataset/dataset.component.html @@ -37,7 +37,10 @@
    {{datasetInfo.description}}
    +
    + +
    - +
    View less @@ -235,7 +238,7 @@ : {{item['labelConcept']}}
    - + diff --git a/portal-2/src/app/landingPages/project/project.component.html b/portal-2/src/app/landingPages/project/project.component.html index 9139c059..24a5d093 100644 --- a/portal-2/src/app/landingPages/project/project.component.html +++ b/portal-2/src/app/landingPages/project/project.component.html @@ -234,10 +234,10 @@ + +
  • Deposit Publications diff --git a/portal-2/src/app/landingPages/publication/publication.component.html b/portal-2/src/app/landingPages/publication/publication.component.html index e6974302..72b15d71 100644 --- a/portal-2/src/app/landingPages/publication/publication.component.html +++ b/portal-2/src/app/landingPages/publication/publication.component.html @@ -57,7 +57,7 @@
      @@ -495,7 +495,7 @@ View more - + @@ -514,7 +514,7 @@ : {{item['labelConcept']}} - + diff --git a/portal-2/src/app/searchPages/searchUtils/dateFilter.module.ts b/portal-2/src/app/searchPages/searchUtils/dateFilter.module.ts index a8589632..0c5dca82 100644 --- a/portal-2/src/app/searchPages/searchUtils/dateFilter.module.ts +++ b/portal-2/src/app/searchPages/searchUtils/dateFilter.module.ts @@ -1,7 +1,7 @@ import { NgModule} from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; -import { MyDatePickerModule } from 'mydatepicker'; +import { MyDatePickerModule } from '../../utils/my-date-picker/my-date-picker.module'; import {DateFilterComponent} from './dateFilter.component'; @NgModule({ imports: [ diff --git a/portal-2/src/app/utils/my-date-picker/directives/my-date-picker.focus.directive.ts b/portal-2/src/app/utils/my-date-picker/directives/my-date-picker.focus.directive.ts new file mode 100644 index 00000000..5508ea6c --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/directives/my-date-picker.input.auto.fill.directive.ts b/portal-2/src/app/utils/my-date-picker/directives/my-date-picker.input.auto.fill.directive.ts new file mode 100644 index 00000000..ef1a1501 --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/index.ts b/portal-2/src/app/utils/my-date-picker/index.ts new file mode 100644 index 00000000..55613d2b --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/index.ts b/portal-2/src/app/utils/my-date-picker/interfaces/index.ts new file mode 100644 index 00000000..ab34b252 --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-calendar-day.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-calendar-day.interface.ts new file mode 100644 index 00000000..d554243a --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-calendar-view-changed.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-calendar-view-changed.interface.ts new file mode 100644 index 00000000..9b9baa5e --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-date-model.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-date-model.interface.ts new file mode 100644 index 00000000..35aa7535 --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-date-range.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-date-range.interface.ts new file mode 100644 index 00000000..e24b319b --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-date.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-date.interface.ts new file mode 100644 index 00000000..99f00796 --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-day-labels.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-day-labels.interface.ts new file mode 100644 index 00000000..f2fcfa24 --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-input-auto-fill.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-input-auto-fill.interface.ts new file mode 100644 index 00000000..695afa92 --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-input-field-changed.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-input-field-changed.interface.ts new file mode 100644 index 00000000..c93530b6 --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-input-focus-blur.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-input-focus-blur.interface.ts new file mode 100644 index 00000000..99678cbb --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-locale.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-locale.interface.ts new file mode 100644 index 00000000..25d268ba --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-month-labels.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-month-labels.interface.ts new file mode 100644 index 00000000..0eede49b --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-month.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-month.interface.ts new file mode 100644 index 00000000..846a23eb --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-options.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-options.interface.ts new file mode 100644 index 00000000..89c26bea --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-week.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-week.interface.ts new file mode 100644 index 00000000..be7bca16 --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/interfaces/my-weekday.interface.ts b/portal-2/src/app/utils/my-date-picker/interfaces/my-weekday.interface.ts new file mode 100644 index 00000000..da1df557 --- /dev/null +++ b/portal-2/src/app/utils/my-date-picker/interfaces/my-weekday.interface.ts @@ -0,0 +1,4 @@ +export interface IMyWeekday { + number: number; + weekday: string; +} diff --git a/portal-2/src/app/utils/my-date-picker/my-date-picker.component.css b/portal-2/src/app/utils/my-date-picker/my-date-picker.component.css new file mode 100644 index 00000000..3c21416d --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/my-date-picker.component.html b/portal-2/src/app/utils/my-date-picker/my-date-picker.component.html new file mode 100644 index 00000000..05c91c89 --- /dev/null +++ b/portal-2/src/app/utils/my-date-picker/my-date-picker.component.html @@ -0,0 +1,57 @@ +
      +
      + +
      + + +
      +
      +
      + + + + + + +
      +
      +
      +
      + + +
      +
      +
      +
      + + +
      +
      +
      + + +
      +
      +
      +
      + + + + + + + + +
      #{{d}}
      {{w.weekNbr}} +
      + {{d.dateObj.day}} +
      +
      +
      +
      diff --git a/portal-2/src/app/utils/my-date-picker/my-date-picker.component.spec.ts b/portal-2/src/app/utils/my-date-picker/my-date-picker.component.spec.ts new file mode 100644 index 00000000..3a9b7407 --- /dev/null +++ b/portal-2/src/app/utils/my-date-picker/my-date-picker.component.spec.ts @@ -0,0 +1,2214 @@ +/// + +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/portal-2/src/app/utils/my-date-picker/my-date-picker.component.ts b/portal-2/src/app/utils/my-date-picker/my-date-picker.component.ts new file mode 100644 index 00000000..77ad87be --- /dev/null +++ b/portal-2/src/app/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; +const myDpStyles: string = require("./my-date-picker.component.css"); +const 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", + styles: [myDpStyles], + template: myDpTpl, + 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/portal-2/src/app/utils/my-date-picker/my-date-picker.module.ts b/portal-2/src/app/utils/my-date-picker/my-date-picker.module.ts new file mode 100644 index 00000000..a638a905 --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/services/my-date-picker.locale.service.ts b/portal-2/src/app/utils/my-date-picker/services/my-date-picker.locale.service.ts new file mode 100644 index 00000000..44c209e9 --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/app/utils/my-date-picker/services/my-date-picker.util.service.ts b/portal-2/src/app/utils/my-date-picker/services/my-date-picker.util.service.ts new file mode 100644 index 00000000..98b51bca --- /dev/null +++ b/portal-2/src/app/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/portal-2/src/assets/sitemap.xml b/portal-2/src/assets/sitemap.xml index 2fc992dc..a040fc58 100644 --- a/portal-2/src/assets/sitemap.xml +++ b/portal-2/src/assets/sitemap.xml @@ -1,102 +1,102 @@ - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - + weekly 0.5 - https://demo.openaire.eu/participate/deposit-publications + demo.openaire.eu/participate/deposit-publications weekly 0.5 - https://demo.openaire.eu/participate/deposit-datasets + demo.openaire.eu/participate/deposit-datasets weekly 0.5