[develop]: Add sortBy # of publicatiosn options in RFOs/RPOs. Add indicator caching option.
This commit is contained in:
parent
f5d85aef86
commit
37a678d571
|
@ -31,6 +31,7 @@
|
|||
"@angular/platform-server": "^16.2.0",
|
||||
"@angular/router": "^16.2.0",
|
||||
"@nguniversal/express-engine": "^16.2.0",
|
||||
"axios": "^1.4.0",
|
||||
"clipboard": "^1.5.16",
|
||||
"express": "^4.15.2",
|
||||
"jquery": "^3.4.1",
|
||||
|
|
65
server.ts
65
server.ts
|
@ -13,12 +13,18 @@ var jsonParser = bodyParser.json()
|
|||
import * as fs from 'fs';
|
||||
import {readFileSync} from "fs";
|
||||
import {properties} from "./src/environments/environment";
|
||||
import axios, {AxiosHeaders} from "axios";
|
||||
import {CacheIndicators} from "./src/app/openaireLibrary/monitor-admin/utils/cache-indicators/cache-indicators";
|
||||
import {UserManagementService} from "./src/app/openaireLibrary/services/user-management.service";
|
||||
import {Session, User} from "./src/app/openaireLibrary/login/utils/helper.class";
|
||||
import {Stakeholder} from "./src/app/openaireLibrary/monitor/entities/stakeholder";
|
||||
// The Express app is exported so that it can be used by serverless Functions.
|
||||
export function app(): express.Express {
|
||||
const server = express();
|
||||
server.use(compression());
|
||||
const distFolder = join(process.cwd(), 'dist/irish-monitor/browser');
|
||||
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
|
||||
let cacheIndicators: CacheIndicators = new CacheIndicators();
|
||||
|
||||
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/main/modules/express-engine)
|
||||
server.engine('html', ngExpressEngine({
|
||||
|
@ -67,6 +73,65 @@ export function app(): express.Express {
|
|||
message: 'action received!'
|
||||
});
|
||||
});
|
||||
|
||||
server.post('/cache/:alias', jsonParser, async (req, res) => {
|
||||
await checkPermissions(req, res, (stakeholder, user) => {
|
||||
if (cacheIndicators.completed(stakeholder._id)) {
|
||||
res.send({
|
||||
id: stakeholder._id,
|
||||
report: cacheIndicators.createReport(stakeholder._id, cacheIndicators.stakeholderToCacheItems(stakeholder), stakeholder.name, user.email)
|
||||
});
|
||||
} else {
|
||||
res.status(409).send('There is another active caching process for this stakeholder');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
server.get('/cache/:alias', async (req, res) => {
|
||||
await checkPermissions(req, res, stakeholder => {
|
||||
if (cacheIndicators.exists(stakeholder._id)) {
|
||||
res.send({
|
||||
id: stakeholder._id,
|
||||
report: cacheIndicators.getReport(stakeholder._id)
|
||||
});
|
||||
} else {
|
||||
res.status(404).send('There is not an active caching process for this stakeholder');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
async function checkPermissions(req, res, access: (stakeholder, user) => void) {
|
||||
let headers: AxiosHeaders = new AxiosHeaders();
|
||||
headers.set('Cookie', req.headers.cookie);
|
||||
let userinfoRes = (await axios.get<any>(UserManagementService.userInfoUrl(), {
|
||||
withCredentials: true,
|
||||
headers: headers
|
||||
}).catch(error => {
|
||||
return error.response;
|
||||
}));
|
||||
if (userinfoRes.status === 200) {
|
||||
let user = new User(userinfoRes.data);
|
||||
let stakeholderRes = (await axios.get<Stakeholder>(properties.monitorServiceAPIURL + '/stakeholder/' + encodeURIComponent(req.params.alias), {
|
||||
withCredentials: true,
|
||||
headers: headers
|
||||
}).catch(error => {
|
||||
return error.response;
|
||||
}));
|
||||
if (stakeholderRes.status === 200) {
|
||||
let stakeholder = stakeholderRes.data;
|
||||
if (Session.isPortalAdministrator(user) || Session.isCurator(stakeholder.type, user)) {
|
||||
access(stakeholder, user);
|
||||
} else {
|
||||
res.status(403).send('You are forbidden to access this resource');
|
||||
}
|
||||
} else {
|
||||
res.status(stakeholderRes.status).send(stakeholderRes.statusText);
|
||||
}
|
||||
} else {
|
||||
res.status(userinfoRes.status).send(userinfoRes.data.message);
|
||||
}
|
||||
}
|
||||
|
||||
server.get('*.*', express.static(distFolder, {
|
||||
maxAge: '1y'
|
||||
}));
|
||||
|
|
|
@ -27,6 +27,7 @@ import {Irish} from "../shared/irish";
|
|||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</div>
|
||||
<cache-indicators *ngIf="stakeholder && isAdmin" [alias]="stakeholder.alias"></cache-indicators>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
|
|
|
@ -9,6 +9,7 @@ import {LogoUrlPipeModule} from "../openaireLibrary/utils/pipes/logoUrlPipe.modu
|
|||
import {AdminLoginGuard} from "../openaireLibrary/login/adminLoginGuard.guard";
|
||||
import {LoginGuard} from "../openaireLibrary/login/loginGuard.guard";
|
||||
import {AdminDashboardGuard} from "../openaireLibrary/monitor-admin/utils/adminDashboard.guard";
|
||||
import {CacheIndicatorsModule} from "../openaireLibrary/monitor-admin/utils/cache-indicators/cache-indicators.module";
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, RouterModule.forChild([
|
||||
|
@ -59,7 +60,7 @@ import {AdminDashboardGuard} from "../openaireLibrary/monitor-admin/utils/adminD
|
|||
}
|
||||
]
|
||||
}
|
||||
]), SideBarModule, LoadingModule, LogoUrlPipeModule],
|
||||
]), SideBarModule, LoadingModule, LogoUrlPipeModule, CacheIndicatorsModule],
|
||||
declarations: [AdminComponent],
|
||||
exports: [AdminComponent]
|
||||
})
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 368ef1aba443cc94d1e95b95c237d3ef2d67e906
|
||||
Subproject commit 35323bd7441d7d21ce785aade0002ee02fdc402a
|
|
@ -2,32 +2,30 @@ import {ChangeDetectorRef, Component} from "@angular/core";
|
|||
import {ActivatedRoute, Router} from "@angular/router";
|
||||
import {FormBuilder} from "@angular/forms";
|
||||
import {BrowseStakeholderBaseComponent} from "../../shared/browse-stakeholder-base.component";
|
||||
import {StakeholderService} from "../../openaireLibrary/monitor/services/stakeholder.service";
|
||||
import {LayoutService} from "../../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
|
||||
import {Option} from "../../openaireLibrary/sharedComponents/input/input.component";
|
||||
import {Stakeholder} from "../../openaireLibrary/monitor/entities/stakeholder";
|
||||
import {SearchDataprovidersService} from "../../openaireLibrary/services/searchDataproviders.service";
|
||||
import {SearchResult} from "../../openaireLibrary/utils/entities/searchResult";
|
||||
import {ResultPreview} from "../../openaireLibrary/utils/result-preview/result-preview";
|
||||
import {Observable, forkJoin, of} from "rxjs";
|
||||
import {forkJoin, Observable, of} from "rxjs";
|
||||
import {catchError} from "rxjs/operators";
|
||||
import {StakeholderPublication} from "../../shared/irish";
|
||||
import {IrishMonitorService} from "../../shared/irish-monitor.service";
|
||||
|
||||
@Component({
|
||||
selector: 'browse-repository',
|
||||
templateUrl: 'browse-repositories.component.html'
|
||||
})
|
||||
export class BrowseRepositoriesComponent extends BrowseStakeholderBaseComponent {
|
||||
filteredStakeholders: StakeholderRepository[];
|
||||
sortBy = 'alphAsc';
|
||||
sortOptions: Option[] = [
|
||||
{value: 'alphAsc', label: 'Alphabetically Asc. (A-Z)'},
|
||||
{value: 'alphDsc', label: 'Alphabetically Dsc. (Z-A)'},
|
||||
{value: 'mostRecent', label: 'Most recent'},
|
||||
{value: 'leastRecent', label: 'Least recent'},
|
||||
{value: 'alphDsc', label: 'Alphabetically Dsc. (Z-A)'}
|
||||
]
|
||||
|
||||
constructor(protected _route: ActivatedRoute,
|
||||
protected _router: Router,
|
||||
protected stakeholderService: StakeholderService,
|
||||
protected irishMonitorService: IrishMonitorService,
|
||||
protected layoutService: LayoutService,
|
||||
protected cdr: ChangeDetectorRef,
|
||||
protected fb: FormBuilder,
|
||||
|
@ -46,15 +44,6 @@ export class BrowseRepositoriesComponent extends BrowseStakeholderBaseComponent
|
|||
this.stakeholders = this.stakeholders.sort((a, b) => b['index_name'].localeCompare(a['index_name']));
|
||||
this.afterStakeholdersInitialized();
|
||||
break;
|
||||
case 'mostRecent':
|
||||
// compare creationDate?
|
||||
this.stakeholders = this.stakeholders.sort((a, b) => Number(b['creationDate']) - Number(a['creationDate']));
|
||||
this.afterStakeholdersInitialized();
|
||||
break;
|
||||
case 'leastRecent':
|
||||
this.stakeholders = this.stakeholders.sort((a, b) => Number(a['creationDate']) - Number(b['creationDate']));
|
||||
this.afterStakeholdersInitialized();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -95,6 +84,7 @@ export class BrowseRepositoriesComponent extends BrowseStakeholderBaseComponent
|
|||
return ResultPreview.searchResultConvert(result, (result.entityType) ? result.entityType : this.typeAsLabel);
|
||||
}
|
||||
}
|
||||
export class StakeholderRepository extends Stakeholder {
|
||||
|
||||
export class StakeholderRepository extends StakeholderPublication {
|
||||
details: any;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ import {OpenaireEntities} from "../openaireLibrary/utils/properties/searchFields
|
|||
<div class="uk-width-expand uk-margin-small-left">
|
||||
<div class="uk-h4 uk-margin-xsmall-bottom uk-text-truncate">{{author.authorGivenName}} {{author.authorFamilyName}}</div>
|
||||
<div class="uk-text-xsmall uk-text-bold uk-margin-bottom">
|
||||
<div *ngIf="totalResults > 0">{{totalResults}} research outcomes</div>
|
||||
<div *ngIf="totalResults > 0">{{totalResults}} {{openaireEntities.RESULTS}}</div>
|
||||
<div *ngIf="author.institutions" class="uk-text-truncate">{{author.institutions.join(", ")}} </div>
|
||||
</div>
|
||||
<div class="uk-flex uk-flex-middle uk-text-small uk-text-italic">
|
||||
|
@ -90,6 +90,7 @@ export class ResearcherComponent extends ResearcherBaseComponent implements OnI
|
|||
stakeholder;
|
||||
isSearch: boolean = false;
|
||||
openaireEntities = OpenaireEntities;
|
||||
|
||||
constructor(protected _router: Router,
|
||||
protected _route: ActivatedRoute,
|
||||
protected seoService: SEOService,
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<div class="uk-padding-remove-left uk-width-expand">
|
||||
<div class="uk-h6 uk-margin-xsmall-bottom uk-text-truncate">{{author.authorGivenName}} {{author.authorFamilyName}}</div>
|
||||
<div class="uk-text-primary uk-text-xsmall uk-text-bold">
|
||||
<div *ngIf="author.resultsCount && author.resultsCount > 0">{{author.resultsCount}} research outcomes</div>
|
||||
<div *ngIf="author.resultsCount && author.resultsCount > 0">{{author.resultsCount}} {{openaireEntities.RESULTS}}</div>
|
||||
<div class="uk-text-truncate" *ngIf="author.institutions">{{author.institutions.join(", ")}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -59,7 +59,7 @@
|
|||
<div *ngIf="orcidStatus == errorCodes.LOADING" class="uk-height-medium uk-position-relative" role="alert">
|
||||
<loading class="uk-position-center"></loading>
|
||||
</div>
|
||||
<div class="uk-flex uk-flex-center">
|
||||
<div class="uk-flex uk-flex-center uk-margin-medium-top">
|
||||
<button *ngIf="authorsToShow.length > 0 && orcidStatus != errorCodes.LOADING && (authorsToShow.length > page*size || authors.length > authorsRendered)" class="uk-button uk-button-default" [class.uk-disabled]="orcidStatus == errorCodes.LOADING" (click)="loadMore()" >Load more</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -12,12 +12,14 @@ import {SEOService} from "../../openaireLibrary/sharedComponents/SEO/SEO.service
|
|||
import {PiwikService} from "../../openaireLibrary/utils/piwik/piwik.service";
|
||||
import {Meta, Title} from "@angular/platform-browser";
|
||||
import {map} from "rxjs/operators";
|
||||
import {OpenaireEntities} from "../../openaireLibrary/utils/properties/searchFields";
|
||||
|
||||
@Component({
|
||||
selector: 'search-researcher',
|
||||
templateUrl: './search-researcher.component.html',
|
||||
})
|
||||
export class SearchResearcherComponent extends BaseComponent implements OnInit {
|
||||
openaireEntities = OpenaireEntities;
|
||||
page: number = 1;
|
||||
size: number = 10;
|
||||
public keyword: string = "";//"paolo manghi";//'0000-0001-7291-3210';
|
||||
|
|
|
@ -7,30 +7,35 @@ import {debounceTime, distinctUntilChanged} from "rxjs/operators";
|
|||
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
|
||||
import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service";
|
||||
import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
|
||||
import {IrishMonitorService} from "./irish-monitor.service";
|
||||
import {StakeholderPublication} from "./irish";
|
||||
import {OpenaireEntities} from "../openaireLibrary/utils/properties/searchFields";
|
||||
|
||||
@Directive()
|
||||
export class BrowseStakeholderBaseComponent extends StakeholderBaseComponent implements OnInit {
|
||||
openaireEntities = OpenaireEntities;
|
||||
stakeholderType: StakeholderType;
|
||||
stakeholders: Stakeholder[] = [];
|
||||
filteredStakeholders: Stakeholder[] = [];
|
||||
stakeholders: StakeholderPublication[] = [];
|
||||
filteredStakeholders: StakeholderPublication[] = [];
|
||||
showLoading: boolean = true;
|
||||
isMobile: boolean = false;
|
||||
|
||||
gridView: boolean = true;
|
||||
sortOptions: Option[] = [
|
||||
{value: null, label: 'Number of Publications'},
|
||||
{value: 'alphAsc', label: 'Alphabetically Asc. (A-Z)'},
|
||||
{value: 'alphDsc', label: 'Alphabetically Dsc. (Z-A)'},
|
||||
/*{value: 'oaDsc', label: '"Open Access %" Dsc.'}*/
|
||||
];
|
||||
pageOptions: number[] = [10, 20, 30, 40];
|
||||
sortBy: string = 'alphAsc';
|
||||
sortBy: string = null;
|
||||
currentPage: number = 1;
|
||||
pageSize: number = 10;
|
||||
parameters = {};
|
||||
keywordControl: FormControl;
|
||||
|
||||
/* Services */
|
||||
protected stakeholderService: StakeholderService;
|
||||
protected irishMonitorService: IrishMonitorService;
|
||||
protected layoutService: LayoutService;
|
||||
protected cdr: ChangeDetectorRef;
|
||||
protected fb: FormBuilder;
|
||||
|
@ -49,10 +54,10 @@ export class BrowseStakeholderBaseComponent extends StakeholderBaseComponent imp
|
|||
if(!this.stakeholderType) {
|
||||
this.navigateToError();
|
||||
}
|
||||
this.subscriptions.push(this.stakeholderService.getStakeholders(this.properties.monitorServiceAPIURL, this.stakeholderType).subscribe(stakeholders => {
|
||||
this.subscriptions.push(this.irishMonitorService.getStakeholdersWithPublications(this.stakeholderType).subscribe(stakeholders => {
|
||||
this.stakeholders = stakeholders;
|
||||
this.filteredStakeholders = stakeholders;
|
||||
this.filteredStakeholders.sort((a, b) => a['name'].localeCompare(b['name']));
|
||||
this.sortByChanged();
|
||||
this.filtering(this.keywordControl.value);
|
||||
}));
|
||||
this.subscriptions.push(this.keywordControl.valueChanges.pipe(debounceTime(200), distinctUntilChanged()).subscribe(value => {
|
||||
|
@ -84,11 +89,8 @@ export class BrowseStakeholderBaseComponent extends StakeholderBaseComponent imp
|
|||
case 'alphDsc':
|
||||
this.stakeholders = this.stakeholders.sort((a, b) => b['name'].localeCompare(a['name']));
|
||||
break;
|
||||
case 'oaDsc':
|
||||
// TODO: dont have an OA percentage yet
|
||||
// this.stakeholders = this.stakeholders.sort((a, b) => b['openAccessPercentage'] - a['openAccessPercentage']);
|
||||
break;
|
||||
default:
|
||||
this.stakeholders = this.stakeholders.sort((a, b) => b.publications - a.publications);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
</div>
|
||||
<div class="uk-flex uk-flex-middle uk-flex-between uk-margin-large-top">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<div class="uk-width-small uk-margin-medium-right">
|
||||
<div *ngIf="sortOptions?.length > 0" class="uk-width-small uk-margin-medium-right">
|
||||
<div input
|
||||
type="select" placeholder="Sort by" inputClass="border-bottom"
|
||||
[options]="sortOptions" [(value)]="sortBy" (valueChange)="sortByChanged()">
|
||||
|
@ -75,6 +75,9 @@
|
|||
{{item.name}}
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="item.publications" class="uk-margin-small-top uk-text-xsmall uk-text-center">
|
||||
{{openaireEntities.PUBLICATIONS}}: {{item.publications | number}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- when OA badges are re-introduced, the below if-statement will have to be moved on its correct div -->
|
||||
<div *ngIf="item.funderType" class="uk-card-footer uk-padding-small uk-background-muted">
|
||||
|
@ -114,6 +117,7 @@
|
|||
<tr>
|
||||
<th>Logo</th>
|
||||
<th>Name</th>
|
||||
<th># of Publications</th>
|
||||
<th *ngIf="stakeholderType === 'funder'">Type</th>
|
||||
<!-- <th class="uk-flex uk-flex-middle">
|
||||
<icon [name]="'open_access'" [flex]="true" [ratio]="0.8" class="open-access"></icon>
|
||||
|
@ -138,6 +142,11 @@
|
|||
{{item.name}}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="uk-text-truncate uk-text-capitalize uk-text-italic uk-text-small uk-text-bold" [title]="item.name">
|
||||
{{item.publications | number}}
|
||||
</div>
|
||||
</td>
|
||||
<td *ngIf="stakeholderType === 'funder'">
|
||||
<div *ngIf="item.funderType" class="uk-text-small uk-text-bold uk-text-capitalize">
|
||||
{{getFunderTypeLabel(item.funderType)}}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import {ChangeDetectorRef, Component} from "@angular/core";
|
||||
import {ActivatedRoute, Router} from "@angular/router";
|
||||
import {StakeholderService} from "../../openaireLibrary/monitor/services/stakeholder.service";
|
||||
import {LayoutService} from "src/app/openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
|
||||
import {FormBuilder} from "@angular/forms";
|
||||
import {BrowseStakeholderBaseComponent} from "../browse-stakeholder-base.component";
|
||||
import {IrishMonitorService} from "../irish-monitor.service";
|
||||
|
||||
@Component({
|
||||
selector: 'browse-stakeholder',
|
||||
|
@ -13,7 +13,7 @@ export class BrowseStakeholdersComponent extends BrowseStakeholderBaseComponent
|
|||
|
||||
constructor(protected _route: ActivatedRoute,
|
||||
protected _router: Router,
|
||||
protected stakeholderService: StakeholderService,
|
||||
protected irishMonitorService: IrishMonitorService,
|
||||
protected layoutService: LayoutService,
|
||||
protected cdr: ChangeDetectorRef,
|
||||
protected fb: FormBuilder) {
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import {Injectable} from "@angular/core";
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
import {Observable} from "rxjs";
|
||||
import {StakeholderPublication} from "./irish";
|
||||
import {properties} from "../../environments/environment";
|
||||
import {Stakeholder, StakeholderType} from "../openaireLibrary/monitor/entities/stakeholder";
|
||||
import {CustomOptions} from "../openaireLibrary/services/servicesUtils/customOptions.class";
|
||||
import {map} from "rxjs/operators";
|
||||
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class IrishMonitorService {
|
||||
|
||||
|
||||
constructor(private http: HttpClient) {
|
||||
}
|
||||
|
||||
public getStakeholdersWithPublications(type: StakeholderType): Observable<StakeholderPublication[]> {
|
||||
return this.http.get<StakeholderPublication[]>(properties.monitorServiceAPIURL + '/publications/' + type, CustomOptions.registryOptions()).pipe(map(stakeholders => {
|
||||
return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholders));
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ import {Portal} from "../openaireLibrary/utils/entities/adminTool/portal";
|
|||
import {StakeholderConfiguration} from "../openaireLibrary/monitor-admin/utils/indicator-utils";
|
||||
import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
|
||||
import {Role} from "../openaireLibrary/login/utils/helper.class";
|
||||
import {Stakeholder} from "../openaireLibrary/monitor/entities/stakeholder";
|
||||
|
||||
export class Irish {
|
||||
public static irishAdminToolsPortalType = "country";
|
||||
|
@ -42,7 +43,7 @@ export class Irish {
|
|||
{icon: 'earth', value: "PUBLIC", label: 'Public'},
|
||||
];
|
||||
|
||||
StakeholderConfiguration.CACHE_INDICATORS = false;
|
||||
StakeholderConfiguration.CACHE_INDICATORS = true;
|
||||
|
||||
LayoutService.HEADER_HEIGHT = '60px';
|
||||
|
||||
|
@ -50,3 +51,7 @@ export class Irish {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
export class StakeholderPublication extends Stakeholder {
|
||||
publications: number;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue