diff --git a/claims/claimsByToken/claimsByToken.component.html b/claims/claimsByToken/claimsByToken.component.html index fca3b5ca..df9bf728 100644 --- a/claims/claimsByToken/claimsByToken.component.html +++ b/claims/claimsByToken/claimsByToken.component.html @@ -2,161 +2,176 @@
-
- -

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

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

Pending Claims

+ +
    +
  • +

    Pending Claims

    + + -
    -
    No pending claims found.
    -
    +
    -
    +
    Note that claims you do not select (approve or disapprove) are considered as approved (but not curated)
    -
    -
    - -
    -
    +
    +
    + + +
    +
    - - {{totalPendingResults.count | number}} pending claims, page {{activePendingPage.page | number}} of {{totalPages(totalPendingResults.count) | number}} - - - - - - - - - - - - - - - - - - - - + + +
    Research Result Claimed By Claimed Date Approve
    {{claim1.userMail}}{{claim1.date}} + + {{totalPendingResults.count | number}} pending claims, page {{activePendingPage.page | number}} of {{totalPages(totalPendingResults.count) | number}} + + + + + + + + + + + + + + + + + + + - - -
    Research Result Claimed By Claimed Date Approve
    {{claim.userMail}}{{claim.date}} - - -
    - + + +
    +
    -
    *Note that claims you did not approved or disapproved are considered as right (but not curated)
    - +
    + You have selected {{(selectedWrong_PendingMode.size+selectedRight_PendingMode.size)}} claims to curate +
    +
    + -

    Already Curated Claims

    + + + +
    +
  • +
  • +

    Curated Claims

    -
    -
    No curated claims found.
    -
    + -
    + -
    -
    - -
    -
    +
    - - {{totalCuratedResults.count | number}} curated claims, page {{activeCuratedPage.page | number}} of {{totalPages(totalCuratedResults.count) | number}} - - +
    +
    + + +
    +
    - - - - - - - - - - - - - - - - - - - - - - - - - + + + + +
    Research ResultClaimed by Claimed Date Curated by Curation Date Approved
    {{claim.userMail}}{{claim.date}}{{claim.curatedBy}}{{claim.curationDate}} + + {{totalCuratedResults.count | number}} curated claims, page {{activeCuratedPage.page | number}} of {{totalPages(totalCuratedResults.count) | number}} + + - + + + + + + + + + + + + + + + + + + + + + + + - - - - -
    Research ResultClaimed by Claimed Date Curated by Curation Date ApprovedActions
    {{claim.userMail}}{{claim.date}}{{claim.curatedBy}}{{claim.curationDate}} + - + -
    - +
    + + + + + + + +
    +
    +
  • +
-
diff --git a/claims/claimsByToken/claimsByToken.component.ts b/claims/claimsByToken/claimsByToken.component.ts index 60544fd6..08962d6b 100644 --- a/claims/claimsByToken/claimsByToken.component.ts +++ b/claims/claimsByToken/claimsByToken.component.ts @@ -1,12 +1,14 @@ -import {Component, ViewChild, Input} from '@angular/core'; +import {Component, ViewChild, ViewChildren, QueryList, Input, ViewEncapsulation} from '@angular/core'; import {Location} from '@angular/common'; import {ActivatedRoute, Params} from '@angular/router'; import {Title, Meta} from '@angular/platform-browser'; import {DataTableDirective} from 'angular-datatables'; import {Observable} from 'rxjs/Observable'; +import { Subject } from 'rxjs/Subject'; import{EnvProperties} from '../../utils/properties/env-properties'; +import {ErrorCodes} from '../../utils/properties/errorCodes'; import {ClaimsDatatablePipe} from '../../utils/pipes/claimsDatatable.pipe'; @@ -20,7 +22,15 @@ import {ClaimsByTokenService} from './claimsByToken.service'; @Component({ selector: 'claims-project-manager', - templateUrl: 'claimsByToken.component.html' + templateUrl: 'claimsByToken.component.html', + styles: [` + #table1_info, #table1_paginate, #table1_length, #table1_filter, + #table2_info, #table2_paginate, #table2_length, #table2_filter{ + display: none; + } + + `], + encapsulation: ViewEncapsulation.None // this used in order styles to work }) export class ClaimsByTokenComponent { @@ -30,29 +40,40 @@ export class ClaimsByTokenComponent { private claims:any = []; public pending_claims: any = []; public curated_claims: any = []; - public selectedRight: Set; - public selectedWrong: Set; - public editable: Set; + public selectedRight_PendingMode: Set; + public selectedWrong_PendingMode: Set; + public selectedRight_CuratedMode: Set; + public selectedWrong_CuratedMode: Set; + public editable: Set; public contact_person: string[] = ["Konstantina", "Argiro", "Katerina"]; + private errorCodes: ErrorCodes; + public pending_status: number; + public curated_status: number; + // when 'valid' show proper claims, when 'invalid' show no matched entry-wanna retry public accessStatus: string;// = "empty"; + public mode: string = "pending"; + public showTables: boolean = true; public rowsOnPage = 5; public sortOrder = "asc"; - public filterQuery:string = ""; - public filterQuery2:string = ""; + public keyword1:string = ""; + public keyword2:string = ""; public activePendingPage:any = {page: 1}; public totalPendingResults:any = {count: 0}; public activeCuratedPage:any = {page: 1}; public totalCuratedResults:any = {count: 0}; + dtTrigger: Subject[] = []; + private triggered: boolean = false; - @ViewChild('mf1') table1: any;//DataTable; - @ViewChild('mf2') table2: any;//DataTable; - @ViewChild('filtered1') filteredItems1; - + dtOptions: DataTables.Settings[] = []; + @ViewChildren(DataTableDirective) + dtElements: QueryList; + //@ViewChild("table1") table1: DataTableDirective; + //@ViewChild("table2") table2: DataTableDirective; @ViewChild (ModalSelect) selectModal : ModalSelect; @ViewChild (ModalLoading) loading : ModalLoading ; @@ -64,7 +85,9 @@ export class ClaimsByTokenComponent { constructor (private route: ActivatedRoute, private claimsByTokenService: ClaimsByTokenService, private _meta: Meta, private _title: Title) { - + this.errorCodes = new ErrorCodes(); + this.pending_status = this.errorCodes.LOADING; + this.curated_status = this.errorCodes.LOADING; } ngOnInit() { this.route.data @@ -73,69 +96,179 @@ export class ClaimsByTokenComponent { }); this.sub = this.route.queryParams.subscribe(params => { + this.mode = "pending"; this.token = params['token']; - this.selectedRight = new Set(); - this.selectedWrong = new Set(); - this.editable = new Set(); - //this.openSelect(); - //this.setMessageSelect("Please select your identity:"); - //this.setOptionsSelect(this.contact_person); + this.selectedRight_PendingMode = new Set(); + this.selectedWrong_PendingMode = new Set(); + this.selectedRight_CuratedMode = new Set(); + this.selectedWrong_CuratedMode = new Set(); + this.editable = new Set(); this.validateJWTandToken(); this.updateTitle("Claims For Project Managers"); } ); + + this.dtOptions[0] = { + //"paging": false, + //"searching": false, + //"lengthChange": false, + "pageLength": this.rowsOnPage, + "columnDefs": [ { + "type": "date", + "targets": 2 + } ], + "order": [[ 2, 'desc' ]] + //"pagingType": 'full_numbers', + /*"language": { + "search": "", + "searchPlaceholder": "Search projects..." + }*/ + }; +console.info("configure dtOptions1: ",this.dtOptions[0]); + + this.dtOptions[1] = { + "pageLength": this.rowsOnPage, + "columnDefs": [ { + "type": "date", + "targets": [2,4] + } ], + "order": [[ 4, 'desc' ]] + }; + +console.info("configure dtOptions2: ",this.dtOptions[1]); + + this.dtTrigger[0] = new Subject(); + this.dtTrigger[1] = new Subject(); } -refreshTable(table:any, $event:any, whichTable: string) { + ngAfterViewInit(): void { + $.fn['dataTable'].ext.search.push((settings, data, dataIndex) => { + if(settings.sTableId == 'table1') { + if (this.filterData(data, this.keyword1)) { + return true; + } + return false; + } else if(settings.sTableId == 'table2') { + if (this.filterData(data, this.keyword2)) { + return true; + } + return false; + } + }); + } + + ngOnDestroy(): void { + $.fn['dataTable'].ext.search.pop(); + // Do not forget to unsubscribe the event + this.dtTrigger[0].unsubscribe(); + this.dtTrigger[1].unsubscribe(); + } + + /* + Trigger a table draw in order to get the initial filtering + */ + triggerInitialLoad(){ + this.triggered = true; + console.info("triggerInitialLoad"); + setTimeout(function(){ + /*var table1 = $('#table1').DataTable(); + table1.page( 0 ).draw( false ); + + var table2 = $('#table2').DataTable(); + table2.page( 0 ).draw( false );*/ + }, 500); + setTimeout(() => { + this.dtTrigger[0].next(); + this.dtTrigger[1].next(); + }); + + } + + rerender(): void { + console.info("RERENDER"); + this.dtElements.forEach((dtElement: DataTableDirective, index: number) => { + dtElement.dtInstance.then((dtInstance: any) => { + // Destroy the table first + dtInstance.destroy(); + + // Call the dtTrigger to rerender again + this.dtTrigger[index].next(); + }); + }); + } + + filterData(row: any, query: string) { + let returnValue: boolean = false; + + if(query) { + for(var i=0; i <3; i++){ + var r= this.filterQuery(row[i], query); + if(r) { + returnValue = true; + break; + } + } + + if(!returnValue) { + return false; + } + } + + return true; + } + + filterQuery(data, query){ + if(data.toLowerCase().indexOf(query.toLowerCase()) > -1){ + return true; + }else{ + return false; + } + } + +refreshTable(page:number, whichTable: string) { + if(whichTable == "pending") { - this.activePendingPage.page = $event.value; + var table = $('#table1').DataTable(); + table.page( page - 1 ).draw( false ); + + var info = table.page.info(); + console.info("records: "+info.recordsDisplay); + + this.activePendingPage.page = page;//$event.value; + this.totalPendingResults.count = info.recordsDisplay; } else if(whichTable == 'curated') { - this.activeCuratedPage.page = $event.value; + var table = $('#table2').DataTable(); + table.page( page - 1 ).draw( false ); + + var info = table.page.info(); + console.info("records: "+info.recordsDisplay); + + this.activeCuratedPage.page = page;//$event.value; + this.totalCuratedResults.count = info.recordsDisplay; } - table.mfActivePage=$event.value; - table.setPage(table.mfActivePage, this.rowsOnPage); -} -public sortByClaimDate1 = (claim: any) => { - return new Date(claim.date); + //table.mfActivePage=$event.value; + //table.setPage(table.mfActivePage, this.rowsOnPage); } -public sortByCurationDate1 = (claim: any) => { - return new Date(claim.curationDate); -} - -public sortByTitle1 = (claim: any) => { - if(claim.targetType != 'project') { - return claim.target.title; - } else { - return claim.source.title; - } -} - -public sortByClaimDate2 = (claim: any) => { - return new Date(claim.date); -} - -public sortByCurationDate2 = (claim: any) => { - console.info(new Date(claim.curationDate)); - return new Date(claim.curationDate); -} - -public sortByTitle2= (claim: any) => { - if(claim.targetType != 'project') { - return claim.target.title; - } else { - return claim.source.title; - } -} - - validateJWTandToken() { if(this.token) { + this.pending_status = this.errorCodes.LOADING; + this.curated_status = this.errorCodes.LOADING; + + this.showTables = false; + this.pending_claims = []; + this.curated_claims = []; + + this.activePendingPage.page = 1; + this.totalPendingResults.count = 0; + this.activeCuratedPage.page = 1; + this.totalCuratedResults.count = 0; + this.claimsByTokenService.getClaims(this.token, this.properties.claimsAPIURL).subscribe( data => { - this.closeLoading(); + //this.closeLoading(); this.accessStatus = "valid"; //console.info(data); this.claims = data.data; @@ -156,10 +289,52 @@ public sortByTitle2= (claim: any) => { this.totalCuratedResults.count = this.curated_claims.length; this.updateTitle("Claims For Project Managers - "+this.project.name); + this.showTables = true; + + if(!this.triggered) { + console.info("initial load"); + this.triggerInitialLoad(); + } else { + console.info("rerender"); + var table1 = $('#table1').DataTable(); + table1.clear(); + + var table2 = $('#table2').DataTable(); + table2.clear(); + + this.rerender(); + } + + this.pending_status = this.errorCodes.DONE; + this.curated_status = this.errorCodes.DONE; }, err => { - this.accessStatus = "invalid"; - console.log(err); + if(err.status == '404') { + this.pending_status = this.errorCodes.NOT_FOUND; + this.curated_status = this.errorCodes.NOT_FOUND; + } else if(err.status == '500') { + this.pending_status = this.errorCodes.ERROR; + this.curated_status = this.errorCodes.ERROR; + } else { + this.pending_status = this.errorCodes.NOT_AVAILABLE; + this.curated_status = this.errorCodes.NOT_AVAILABLE; + } + this.showTables = true; + + if(!this.triggered) { + this.triggerInitialLoad(); + } else { + var table1 = $('#table1').DataTable(); + table1.clear(); + + var table2 = $('#table2').DataTable(); + table2.clear(); + + this.rerender(); + } + + this.accessStatus = "invalid"; + console.log(err); } ); } else { @@ -167,70 +342,150 @@ public sortByTitle2= (claim: any) => { } } - selectApprove(id:string, event) { + selectApprove(id:string, event, mode: string) { var value = event.currentTarget.checked; if(value){ - this.selectedRight.add(id); - this.selectedWrong.delete(id); - console.info(this.selectedRight); + if(mode == "pending") { + this.selectedRight_PendingMode.add(id); + this.selectedWrong_PendingMode.delete(id); + } else { + this.selectedRight_CuratedMode.add(id); + this.selectedWrong_CuratedMode.delete(id); + } }else{ - this.selectedRight.delete(id); - console.info(this.selectedRight); + if(mode == "pending") { + this.selectedRight_PendingMode.delete(id); + } + // } else { + // this.selectedRight_CuratedMode.delete(id); + // this.selectedWrong_CuratedMode.add(id); + // } } } - selectDisapprove(id:string,event) { + selectDisapprove(id:string, event, mode: string) { var value = event.currentTarget.checked; if(value){ - this.selectedWrong.add(id); - this.selectedRight.delete(id); + if(mode == "pending") { + this.selectedWrong_PendingMode.add(id); + this.selectedRight_PendingMode.delete(id); + } else { + this.selectedWrong_CuratedMode.add(id); + this.selectedRight_CuratedMode.delete(id); + } }else{ - this.selectedWrong.delete(id); + if(mode == "pending") { + this.selectedWrong_PendingMode.delete(id); + } + // } else { + // this.selectedWrong_CuratedMode.delete(id); + // this.selectedRight_CuratedMode.add(id); + // } } } - isSelectedRight(id:string) { - return this.selectedRight.has(id); + isSelected(id:string, set:Set) { + return set.has(id); } - +/* isSelectedWrong(id:string) { return this.selectedWrong.has(id); } - - isRight(claim: any) { - //claim.approved = true; - if(this.isSelectedRight(claim.id)) { +*/ + isRight_CuratedMode(claim: any) { + if(this.isSelected(claim.id, this.selectedRight_CuratedMode)) { return true; - } else if(claim.approved == true && !this.isSelectedWrong(claim.id)) { + } else if(claim.approved == true && !this.isSelected(claim.id, this.selectedWrong_CuratedMode)) { return true; } return false; } - isWrong(claim: any) { - if(this.isSelectedWrong(claim.id)) { + isWrong_CuratedMode(claim: any) { + if(this.isSelected(claim.id, this.selectedWrong_CuratedMode)) { return true; - } else if(claim.approved == false && !this.isSelectedRight(claim.id)) { + } else if(claim.approved == false && !this.isSelected(claim.id, this.selectedRight_CuratedMode)) { return true; } return false; } + cancelEditOfCuration(claim: any) { + console.info("cancelEditOfCuration - approved:"+claim.approved); + if(claim.approved) { + //this.selectedRight_CuratedMode.add(claim.id); + this.selectedWrong_CuratedMode.delete(claim.id); + } else { + this.selectedRight_CuratedMode.delete(claim.id); + //this.selectedWrong_CuratedMode.add(claim.id); + } + } + + saveEdited(claim: any, editable_index: number) { + this.curated_status = this.errorCodes.LOADING; + + let approved: boolean = this.isRight_CuratedMode(claim); + + if(approved == claim.approved) { + this.selectedRight_CuratedMode.delete(claim.id); + this.selectedWrong_CuratedMode.delete(claim.id); + this.editable.delete(editable_index); + + this.curated_status = this.errorCodes.DONE; + } else { + let claimCurationInfo: {"id": string, "approved": boolean} = {"id": claim.id, "approved": approved}; + + this.claimsByTokenService.updateClaimCuration(claimCurationInfo, this.properties.claimsAPIURL).subscribe( + data => { + console.info(data); + this.selectedRight_CuratedMode.delete(claim.id); + this.selectedWrong_CuratedMode.delete(claim.id); + this.editable.delete(editable_index); + + this.validateJWTandToken(); + }, + err => { + console.log(err); + this.curated_status = this.errorCodes.NOT_SAVED; + } + ); + } + } + saveChanges() { - console.info("Changes Saved!"); - this.claimsByTokenService.updateClaimsCuration(this.selectedRight, this.selectedWrong, this.properties.claimsAPIURL).subscribe( + this.pending_status = this.errorCodes.LOADING; + //this.openLoading(); + console.info("Changes Saved!, right-wrong", this.selectedRight_PendingMode, this.selectedWrong_PendingMode); + this.claimsByTokenService.updateClaimsCuration(this.selectedRight_PendingMode, this.selectedWrong_PendingMode, this.properties.claimsAPIURL).subscribe( data => { - console.info(data); + //this.closeLoading(); + console.info(data); + this.mode = "curated"; + this.clearCheckboxes(); + this.validateJWTandToken(); }, err => { - console.log(err); + //this.closeLoading(); + console.log(err); + this.pending_status = this.errorCodes.NOT_SAVED; } ); - } + clearCheckboxes() { + this.pending_status = this.errorCodes.LOADING; + this.selectedRight_PendingMode.clear(); + this.selectedWrong_PendingMode.clear(); + this.pending_status = this.errorCodes.DONE; + } + + public openLoading(){ + if(this.loading){ + this.loading.open(); + } + } public closeLoading(){ if(this.loading){ this.loading.close(); diff --git a/claims/claimsByToken/claimsByToken.module.ts b/claims/claimsByToken/claimsByToken.module.ts index 100f6abb..79fa183b 100644 --- a/claims/claimsByToken/claimsByToken.module.ts +++ b/claims/claimsByToken/claimsByToken.module.ts @@ -16,7 +16,7 @@ import {PagingModule} from '../../utils/paging.module'; import {ClaimsDatatablePipe} from '../../utils/pipes/claimsDatatable.pipe'; import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; - +import {ErrorMessagesModule} from '../../utils/errorMessages.module'; @NgModule({ imports: [ @@ -26,8 +26,8 @@ import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; ClaimEntityFormatterModule, SelectModalModule, LoadingModalModule, - PagingModule - + PagingModule, + ErrorMessagesModule ], providers:[ ClaimsByTokenService, diff --git a/claims/claimsByToken/claimsByToken.service.ts b/claims/claimsByToken/claimsByToken.service.ts index ae0ee318..e81e9149 100644 --- a/claims/claimsByToken/claimsByToken.service.ts +++ b/claims/claimsByToken/claimsByToken.service.ts @@ -44,7 +44,7 @@ export class ClaimsByTokenService { let claimsCurationInfo: any = []; //e.g.: [{"id":"2","approved":true},{"id":"1","approved":true}] selectedRight.forEach(function(selected) { - console.info(selected); + //console.info(selected); let claimCurationInfo: {"id": string, "approved": boolean} = {"id": selected, "approved": true}; claimsCurationInfo.push(claimCurationInfo); }); @@ -54,7 +54,7 @@ export class ClaimsByTokenService { claimsCurationInfo.push(claimCurationInfo); }); - console.info("\n\n"+claimsCurationInfo); + console.info(claimsCurationInfo); let body = JSON.stringify( claimsCurationInfo ); @@ -67,6 +67,24 @@ export class ClaimsByTokenService { .catch(this.handleError); } + + updateClaimCuration( claimCurationInfo: {"id": string, "approved": boolean}, apiURL:string) { + let url = apiURL + "curate/bulk"; + let claimsCurationInfo: any = []; //e.g.: [{"id":"2","approved":true},{"id":"1","approved":true}] + claimsCurationInfo.push(claimCurationInfo); + + console.info(claimsCurationInfo); + + let body = JSON.stringify( claimsCurationInfo ); + console.warn('Json body: : '+body); + let headers = new Headers({ 'Content-Type': 'application/json' }); + let options = new RequestOptions({ headers: headers }); + return this.http.post(url, body, CustomOptions.getAuthOptionsWithBody()) + .map(res => res.json()) + .do(request => console.info("Insert Response:"+request.status) ) + .catch(this.handleError); + } + private handleError (error: Response) { // in a real world app, we may send the error to some remote logging infrastructure // instead of just logging it to the console diff --git a/utils/errorMessages.component.ts b/utils/errorMessages.component.ts index 4c1feac9..019082a7 100644 --- a/utils/errorMessages.component.ts +++ b/utils/errorMessages.component.ts @@ -24,7 +24,11 @@ import {ErrorCodes} from './properties/errorCodes'; No {{type}} found
Requested page out of bounds
+ [class]="(tab_error_class ? 'uk-margin-top' : 'uk-animation-fade') + ' uk-alert uk-alert-warning'" role="alert">Requested page out of bounds +
+
Changes could not be saved +
` }) diff --git a/utils/properties/errorCodes.ts b/utils/properties/errorCodes.ts index 479c80e5..899273f5 100644 --- a/utils/properties/errorCodes.ts +++ b/utils/properties/errorCodes.ts @@ -6,4 +6,5 @@ export class ErrorCodes { public NOT_AVAILABLE = 4; public OUT_OF_BOUND = 5; public NOT_FOUND = 6; + public NOT_SAVED = 7; }