Compare commits
13 Commits
main
...
recommenda
Author | SHA1 | Date |
---|---|---|
Konstantina Galouni | fe32746cef | |
Konstantina Galouni | 5c8c31ae45 | |
Konstantina Galouni | b48796dc47 | |
Konstantina Galouni | 0b75c0b3dd | |
Konstantina Galouni | f32dfc0ac6 | |
Alex Martzios | 1d3ab8f645 | |
Alex Martzios | deaa8a33a0 | |
Alex Martzios | 3ddf7ac4fd | |
Alex Martzios | 8ea9cd5dbc | |
Alex Martzios | fe3a439ff0 | |
Alex Martzios | 667c9b1c5f | |
Alex Martzios | d4a092ed7c | |
Alex Martzios | 582285c8b2 |
71
angular.json
71
angular.json
|
@ -212,77 +212,6 @@
|
||||||
"src/assets"
|
"src/assets"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"server": {
|
|
||||||
"builder": "@angular-devkit/build-angular:server",
|
|
||||||
"options": {
|
|
||||||
"outputPath": "dist/eosc/server",
|
|
||||||
"main": "server.ts",
|
|
||||||
"tsConfig": "src/tsconfig.server.json",
|
|
||||||
"sourceMap": true,
|
|
||||||
"optimization": false,
|
|
||||||
"buildOptimizer": false
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"development": {
|
|
||||||
"outputHashing": "media",
|
|
||||||
"sourceMap": false,
|
|
||||||
"optimization": true,
|
|
||||||
"vendorChunk": true,
|
|
||||||
"buildOptimizer": true
|
|
||||||
},
|
|
||||||
"beta": {
|
|
||||||
"outputHashing": "media",
|
|
||||||
"fileReplacements": [
|
|
||||||
{
|
|
||||||
"replace": "src/environments/environment.ts",
|
|
||||||
"with": "src/environments/environment.beta.ts"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"sourceMap": false,
|
|
||||||
"optimization": true,
|
|
||||||
"buildOptimizer": true
|
|
||||||
},
|
|
||||||
"production": {
|
|
||||||
"outputHashing": "media",
|
|
||||||
"fileReplacements": [
|
|
||||||
{
|
|
||||||
"replace": "src/environments/environment.ts",
|
|
||||||
"with": "src/environments/environment.prod.ts"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"sourceMap": false,
|
|
||||||
"optimization": true,
|
|
||||||
"buildOptimizer": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"defaultConfiguration": ""
|
|
||||||
},
|
|
||||||
"serve-ssr": {
|
|
||||||
"builder": "@nguniversal/builders:ssr-dev-server",
|
|
||||||
"options": {
|
|
||||||
"browserTarget": "eosc:build",
|
|
||||||
"serverTarget": "eosc:server"
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"browserTarget": "eosc:build:production",
|
|
||||||
"serverTarget": "eosc:server:production"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"prerender": {
|
|
||||||
"builder": "@nguniversal/builders:prerender",
|
|
||||||
"options": {
|
|
||||||
"browserTarget": "eosc:build:production",
|
|
||||||
"serverTarget": "eosc:server:production",
|
|
||||||
"routes": [
|
|
||||||
"/"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
13
package.json
13
package.json
|
@ -11,12 +11,6 @@
|
||||||
"webpack-bundle-analyzer": "ng build --stats-json && webpack-bundle-analyzer dist/eosc/browser/stats-es2015.json --host 0.0.0.0",
|
"webpack-bundle-analyzer": "ng build --stats-json && webpack-bundle-analyzer dist/eosc/browser/stats-es2015.json --host 0.0.0.0",
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
"e2e": "ng e2e",
|
"e2e": "ng e2e",
|
||||||
"dev:ssr": "ng run eosc:serve-ssr",
|
|
||||||
"serve:ssr": "node dist/eosc/server/main.js",
|
|
||||||
"build:ssr-dev": "npm run build-dev && ng run eosc:server:development",
|
|
||||||
"build:ssr-beta": "npm run build-beta && ng run eosc:server:beta",
|
|
||||||
"build:ssr-prod": "npm run build-prod && ng run eosc:server:production",
|
|
||||||
"prerender": "ng run eosc:prerender",
|
|
||||||
"after-build-clean": "rm -rf dist/eosc/browser/assets/common-assets/.git/ src/app/openaireLibrary/.git node_modules .angular .git*"
|
"after-build-clean": "rm -rf dist/eosc/browser/assets/common-assets/.git/ src/app/openaireLibrary/.git node_modules .angular .git*"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
|
@ -31,12 +25,9 @@
|
||||||
"@angular/material": "^16.1.7",
|
"@angular/material": "^16.1.7",
|
||||||
"@angular/platform-browser": "^16.1.8",
|
"@angular/platform-browser": "^16.1.8",
|
||||||
"@angular/platform-browser-dynamic": "^16.1.8",
|
"@angular/platform-browser-dynamic": "^16.1.8",
|
||||||
"@angular/platform-server": "^16.1.8",
|
|
||||||
"@angular/router": "^16.1.8",
|
"@angular/router": "^16.1.8",
|
||||||
"@nguniversal/express-engine": "^16.1.1",
|
|
||||||
"clipboard": "^1.5.16",
|
"clipboard": "^1.5.16",
|
||||||
"core-js": "^2.5.4",
|
"core-js": "^2.5.4",
|
||||||
"express": "^4.15.2",
|
|
||||||
"jquery": "^3.4.1",
|
"jquery": "^3.4.1",
|
||||||
"ng-recaptcha": "^12.0.2",
|
"ng-recaptcha": "^12.0.2",
|
||||||
"prom-client": "^11.3.0",
|
"prom-client": "^11.3.0",
|
||||||
|
@ -44,6 +35,7 @@
|
||||||
"ts-md5": "^1.2.0",
|
"ts-md5": "^1.2.0",
|
||||||
"tslib": "^2.0.0",
|
"tslib": "^2.0.0",
|
||||||
"uikit": "3.16.24",
|
"uikit": "3.16.24",
|
||||||
|
"uuid": "^10.0.0",
|
||||||
"zone.js": "~0.13.1"
|
"zone.js": "~0.13.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -51,10 +43,7 @@
|
||||||
"@angular/cli": "^16.1.7",
|
"@angular/cli": "^16.1.7",
|
||||||
"@angular/compiler-cli": "^16.1.8",
|
"@angular/compiler-cli": "^16.1.8",
|
||||||
"@angular/language-service": "^16.1.8",
|
"@angular/language-service": "^16.1.8",
|
||||||
"@nguniversal/builders": "^16.1.1",
|
|
||||||
"@types/express": "^4.17.0",
|
|
||||||
"@types/compression": "^1.7.0",
|
"@types/compression": "^1.7.0",
|
||||||
"@types/node": "^12.11.1",
|
|
||||||
"@types/jasmine": "~3.6.0",
|
"@types/jasmine": "~3.6.0",
|
||||||
"@types/jasminewd2": "~2.0.3",
|
"@types/jasminewd2": "~2.0.3",
|
||||||
"codelyzer": "^6.0.0",
|
"codelyzer": "^6.0.0",
|
||||||
|
|
110
server.ts
110
server.ts
|
@ -1,110 +0,0 @@
|
||||||
import 'zone.js/node';
|
|
||||||
|
|
||||||
import { ngExpressEngine } from '@nguniversal/express-engine';
|
|
||||||
import * as express from 'express';
|
|
||||||
import * as compression from 'compression';
|
|
||||||
import { join } from 'path';
|
|
||||||
|
|
||||||
import { AppServerModule } from './src/main.server';
|
|
||||||
import { APP_BASE_HREF } from '@angular/common';
|
|
||||||
import { existsSync } from 'fs';
|
|
||||||
import {Prometheus} from "./prometheus";
|
|
||||||
import {Counter} from "prom-client";
|
|
||||||
import {REQUEST, RESPONSE} from "./src/app/openaireLibrary/utils/tokens";
|
|
||||||
|
|
||||||
// The Express app is exported so that it can be used by serverless Functions.
|
|
||||||
export function app() {
|
|
||||||
const server = express();
|
|
||||||
server.use(compression());
|
|
||||||
const distFolder = join(process.cwd(), 'dist/eosc/browser');
|
|
||||||
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
|
|
||||||
|
|
||||||
const prometheus: Prometheus = new Prometheus();
|
|
||||||
|
|
||||||
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
|
|
||||||
server.engine('html', ngExpressEngine({
|
|
||||||
bootstrap: AppServerModule,
|
|
||||||
inlineCriticalCss: false
|
|
||||||
}));
|
|
||||||
|
|
||||||
server.set('view engine', 'html');
|
|
||||||
server.set('views', distFolder);
|
|
||||||
|
|
||||||
// Example Express Rest API endpoints
|
|
||||||
// server.get('/api/**', (req, res) => { });
|
|
||||||
// Serve static files from /browser
|
|
||||||
server.get('*.*', express.static(distFolder, {
|
|
||||||
maxAge: '1y'
|
|
||||||
}));
|
|
||||||
|
|
||||||
server.get('/metrics', (req, res) => {
|
|
||||||
res.set('Content-Type', prometheus.register.contentType);
|
|
||||||
res.end(prometheus.register.metrics());
|
|
||||||
});
|
|
||||||
|
|
||||||
// All regular routes use the Universal engine
|
|
||||||
server.get('*', (req, res) => {
|
|
||||||
let start = new Date();
|
|
||||||
let counter: Counter = prometheus.counters.get(req.path);
|
|
||||||
if(counter !== undefined) {
|
|
||||||
counter.inc(1, new Date());
|
|
||||||
res.render(indexHtml, {
|
|
||||||
req, providers: [
|
|
||||||
{
|
|
||||||
provide: APP_BASE_HREF,
|
|
||||||
useValue: req.baseUrl
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: REQUEST, useValue: (req)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: RESPONSE, useValue: (res)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
// event triggers when express is done sending response
|
|
||||||
res.on('finish', function() {
|
|
||||||
console.log(new Date().getTime() - start.getTime());
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
res.render(indexHtml, {
|
|
||||||
req, providers: [
|
|
||||||
{
|
|
||||||
provide: APP_BASE_HREF,
|
|
||||||
useValue: req.baseUrl
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: REQUEST, useValue: (req)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: RESPONSE, useValue: (res)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return server;
|
|
||||||
}
|
|
||||||
|
|
||||||
function run() {
|
|
||||||
const port = process.env.PORT || 4000;
|
|
||||||
|
|
||||||
// Start up the Node server
|
|
||||||
const server = app();
|
|
||||||
server.listen(port, () => {
|
|
||||||
console.log(`Node Express server listening on http://localhost:${port}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Webpack will replace 'require' with '__webpack_require__'
|
|
||||||
// '__non_webpack_require__' is a proxy to Node 'require'
|
|
||||||
// The below code is to ensure that the server is run only when not requiring the bundle.
|
|
||||||
declare const __non_webpack_require__: NodeRequire;
|
|
||||||
const mainModule = __non_webpack_require__.main;
|
|
||||||
const moduleFilename = mainModule && mainModule.filename || '';
|
|
||||||
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
|
|
||||||
export * from './src/main.server';
|
|
|
@ -111,6 +111,14 @@ const routes: Routes = [
|
||||||
// redirectTo: ''
|
// redirectTo: ''
|
||||||
loadChildren: () => import('./searchPages/advanced/advancedSearchProjects.module').then(m => m.LibAdvancedSearchProjectsModule)
|
loadChildren: () => import('./searchPages/advanced/advancedSearchProjects.module').then(m => m.LibAdvancedSearchProjectsModule)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'recommendations',
|
||||||
|
loadChildren: () => import('./recommendations/recommendations.module').then(m => m.RecommendationsModule)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'natural-language-search',
|
||||||
|
loadChildren: () => import('./natural-language-search/natural-language-search.module').then(m => m.NaturalLanguageSearchModule)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'reload',
|
path: 'reload',
|
||||||
loadChildren: () => import('./reload/libReload.module').then(m => m.LibReloadModule),
|
loadChildren: () => import('./reload/libReload.module').then(m => m.LibReloadModule),
|
||||||
|
|
|
@ -77,7 +77,7 @@ export class AppComponent {
|
||||||
logoUrl: this.agg.logoUrl,
|
logoUrl: this.agg.logoUrl,
|
||||||
logoSmallUrl: this.agg.logoUrl,
|
logoSmallUrl: this.agg.logoUrl,
|
||||||
position: 'left',
|
position: 'left',
|
||||||
menuPosition: 'right',
|
menuPosition: 'center',
|
||||||
badge: false,
|
badge: false,
|
||||||
darkBg: false
|
darkBg: false
|
||||||
};
|
};
|
||||||
|
@ -122,7 +122,9 @@ export class AppComponent {
|
||||||
null, null, "alpha-badge", null, "_blank", "internal", false,
|
null, null, "alpha-badge", null, "_blank", "internal", false,
|
||||||
[
|
[
|
||||||
new MenuItem("recommendations", "Community Recommendations", "https://test.darelab.athenarc.gr/crps/", "", false, [], null, {}),
|
new MenuItem("recommendations", "Community Recommendations", "https://test.darelab.athenarc.gr/crps/", "", false, [], null, {}),
|
||||||
new MenuItem("nl-search", "NL Search", "https://darelab.athenarc.gr/nl_search/fc4eosc", "", false, [], null, {})
|
new MenuItem("nl-search", "NL Search", "https://darelab.athenarc.gr/nl_search/fc4eosc", "", false, [], null, {}),
|
||||||
|
new MenuItem("category-to-item", "Dev - Category to Item", "", "/recommendations/category-to-item", false, [], null, {}),
|
||||||
|
new MenuItem("natural-language-search", "Dev - NL Search", "", "/natural-language-search", false, [], null, {})
|
||||||
],
|
],
|
||||||
"Alpha"
|
"Alpha"
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,6 +16,8 @@ import {HttpInterceptorService} from "./openaireLibrary/http-interceptor.service
|
||||||
import {ErrorInterceptorService} from "./openaireLibrary/error-interceptor.service";
|
import {ErrorInterceptorService} from "./openaireLibrary/error-interceptor.service";
|
||||||
import {DEFAULT_TIMEOUT, TimeoutInterceptor} from "./openaireLibrary/timeout-interceptor.service";
|
import {DEFAULT_TIMEOUT, TimeoutInterceptor} from "./openaireLibrary/timeout-interceptor.service";
|
||||||
import {ConfigurationService} from "./openaireLibrary/utils/configuration/configuration.service";
|
import {ConfigurationService} from "./openaireLibrary/utils/configuration/configuration.service";
|
||||||
|
import {RouteReuseStrategy} from '@angular/router';
|
||||||
|
import {CustomRouteReuseStrategy} from './openaireLibrary/shared/custom-route-reuse-strategy';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -34,6 +36,7 @@ import {ConfigurationService} from "./openaireLibrary/utils/configuration/config
|
||||||
exports: [AppComponent],
|
exports: [AppComponent],
|
||||||
providers: [
|
providers: [
|
||||||
ConfigurationService,
|
ConfigurationService,
|
||||||
|
{provide: RouteReuseStrategy, useClass: CustomRouteReuseStrategy},
|
||||||
{provide: APP_ID, useValue: 'eosc'},
|
{provide: APP_ID, useValue: 'eosc'},
|
||||||
{
|
{
|
||||||
provide: HTTP_INTERCEPTORS,
|
provide: HTTP_INTERCEPTORS,
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import {ServerModule} from '@angular/platform-server';
|
|
||||||
|
|
||||||
import { AppModule } from './app.module';
|
|
||||||
import { AppComponent } from './app.component';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
AppModule,
|
|
||||||
ServerModule
|
|
||||||
],
|
|
||||||
bootstrap: [AppComponent],
|
|
||||||
})
|
|
||||||
export class AppServerModule {}
|
|
|
@ -12,44 +12,13 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div search-input [(value)]="keyword"
|
<div search-input [(value)]="keyword"
|
||||||
[placeholder]="'Search in FAIRCORE4EOSC'" (searchEmitter)="goTo()"
|
[placeholder]="'Search in FAIRCORE4EOSC'" (searchEmitter)="goTo()"
|
||||||
[searchInputClass]="'inner background'"></div>
|
[searchInputClass]="'inner background'"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="image-front-topbar">-->
|
|
||||||
<!-- <div class="uk-section uk-section-small home-background">-->
|
|
||||||
<!-- <div id="searchForm" class="uk-container uk-container-large uk-section uk-section-xsmall uk-padding-remove-bottom">-->
|
|
||||||
<!-- <div class="uk-grid uk-flex uk-flex-center uk-margin-small-top">-->
|
|
||||||
<!-- <div class="uk-width-1-1 uk-width-auto@m uk-first-column"><div id="searchImage"></div></div>-->
|
|
||||||
<!-- <div class="uk-width-expand uk-padding-remove-vertical search_box_bg" uk-scrollspy="target: [uk-scrollspy-class]; cls: uk-animation-slide-bottom-medium; delay: 200">-->
|
|
||||||
<!-- <div class="uk-flex uk-flex-center uk-flex-wrap">-->
|
|
||||||
<!-- <div class="uk-width-xlarge@l uk-width-large">-->
|
|
||||||
<!-- <div class="uk-flex uk-flex-center uk-child-width-1-1">-->
|
|
||||||
<!-- <div [class.uk-invisible]="disableSelect" uk-scrollspy-class>-->
|
|
||||||
<!-- <advanced-search-input (searchEmitter)="goTo(true)">-->
|
|
||||||
<!-- <entities-selection #entities [simpleView]="true" currentEntity="all" [selectedEntity]="selectedEntity"-->
|
|
||||||
<!-- (selectionChange)="entityChanged($event)" (disableSelectEmitter)="disableSelectChange($event)"-->
|
|
||||||
<!-- [onChangeNavigate]="false" class="uk-width-2-5"></entities-selection>-->
|
|
||||||
<!-- <div class="uk-width-expand" input placeholder="Scholary works" [hint]="'Search in OpenAIRE'"-->
|
|
||||||
<!-- [(value)]="keyword" tooltip="true"></div>-->
|
|
||||||
<!-- </advanced-search-input>-->
|
|
||||||
<!-- <div *ngIf="selectedEntity === 'result' && !entities.input.focused" class="uk-dropdown uk-display-block uk-margin-top uk-width-auto">-->
|
|
||||||
<!-- <div class="uk-padding-small">-->
|
|
||||||
<!-- <quick-selections [resultTypes]="resultTypes" [quickFilter]="resultsQuickFilter"></quick-selections>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<div class="uk-section uk-container uk-container-large">
|
<div class="uk-section uk-container uk-container-large">
|
||||||
<div class="contentbox uk-grid uk-child-width-1-1 uk-child-width-1-2@l">
|
<div class="contentbox uk-grid uk-child-width-1-1 uk-child-width-1-2@l">
|
||||||
<div>
|
<div>
|
||||||
|
@ -73,4 +42,85 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<img src="/assets/home/cloud.svg" class="cloudSvg">
|
<img src="/assets/home/cloud.svg" class="cloudSvg">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="author-recommendations">
|
||||||
|
<div class="uk-section uk-container uk-container-large">
|
||||||
|
<hr class="uk-margin-large-bottom">
|
||||||
|
<ng-container *ngIf="!user">
|
||||||
|
<div class="uk-flex uk-flex-column uk-flex-middle uk-flex-center uk-padding uk-padding-remove-bottom uk-margin-small-bottom">
|
||||||
|
<span class="uk-h4 uk-text-center uk-width-1-2@m">
|
||||||
|
Login and receive recommendations based on your ORCID.
|
||||||
|
</span>
|
||||||
|
<a class="uk-button uk-button-primary uk-text-uppercase uk-margin-top"
|
||||||
|
(click)="logIn()">
|
||||||
|
Login
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="uk-text-right">
|
||||||
|
<img class="uk-margin-large-right" src="assets/recommendations/asset-3.svg" style="width: 225px;">
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="user">
|
||||||
|
<ng-container *ngIf="user.orcid">
|
||||||
|
<div *ngIf="recommendations">
|
||||||
|
<div class="uk-section uk-section-small">
|
||||||
|
<div *ngFor="let item of recommendations | keyvalue;" class="uk-margin-large-bottom">
|
||||||
|
<div class="uk-flex uk-flex-middle">
|
||||||
|
<icon [name]="'recommendations'" [flex]="true" [ratio]="1.5"></icon>
|
||||||
|
<span class="uk-margin-left">Recommended for you in relation to <span class="uk-text-bold uk-text-uppercase">{{item.key}}</span></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div class="uk-grid uk-child-width-1-3@m uk-margin-top" uk-height-match=".uk-card" uk-grid>
|
||||||
|
<div *ngFor="let result of item.value | keyvalue;">
|
||||||
|
<recommendation-card [result]="result.value"></recommendation-card>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<div class="uk-slider uk-margin-top" uk-slider>
|
||||||
|
<ul class="uk-slider-items" uk-height-match=".uk-card">
|
||||||
|
<li *ngFor="let slide of resultsSlider(item.value); let i = index" class="uk-width-1-1">
|
||||||
|
<div class="uk-padding">
|
||||||
|
<div class="uk-grid uk-child-width-1-3@m" uk-grid>
|
||||||
|
<ng-container *ngIf="i === 0">
|
||||||
|
<div *ngFor="let result of slide | keyvalue;" uk-scrollspy-class>
|
||||||
|
<recommendation-card [result]="result.value"></recommendation-card>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="i !== 0">
|
||||||
|
<div *ngFor="let result of slide | keyvalue;">
|
||||||
|
<recommendation-card [result]="result.value"></recommendation-card>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="uk-slider-nav uk-dotnav uk-flex-center uk-margin-medium-top"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="!recommendations" class="uk-flex uk-flex-middle uk-flex-center uk-margin-bottom">
|
||||||
|
<div class="uk-h6 uk-text-center">
|
||||||
|
No recommendations found based on your ORCID.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="!user.orcid">
|
||||||
|
<div class="uk-flex uk-flex-column uk-flex-middle uk-flex-center uk-padding uk-padding-remove-bottom uk-margin-small-bottom">
|
||||||
|
<span class="uk-h4 uk-text-center uk-width-1-2@m">
|
||||||
|
Please logout and login with your ORCID account.
|
||||||
|
</span>
|
||||||
|
<a class="uk-button uk-button-primary uk-text-uppercase uk-margin-top"
|
||||||
|
(click)="logOut()">
|
||||||
|
Logout
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="uk-text-right">
|
||||||
|
<img class="uk-margin-large-right" src="assets/recommendations/asset-3.svg" style="width: 225px;">
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
@ -1,61 +1,24 @@
|
||||||
// import {Component, Inject} from "@angular/core";
|
import {ChangeDetectorRef, Component} from '@angular/core';
|
||||||
// import {DOCUMENT} from "@angular/common";
|
import {Subscription} from 'rxjs';
|
||||||
// import {Meta, Title} from "@angular/platform-browser";
|
import {Router} from '@angular/router';
|
||||||
// import {properties} from "../../environments/environment";
|
|
||||||
//
|
|
||||||
// @Component({
|
|
||||||
// selector: 'home',
|
|
||||||
// templateUrl: 'home.component.html',
|
|
||||||
// })
|
|
||||||
// export class HomeComponent {
|
|
||||||
//
|
|
||||||
// constructor(@Inject(DOCUMENT) readonly document: Document, private _meta: Meta, private _title: Title) {
|
|
||||||
// let title = "EOSC Explore";
|
|
||||||
//
|
|
||||||
// this._title.setTitle(title);
|
|
||||||
// this._meta.updateTag({content:title},"property='og:title'");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /** The Window object from Document defaultView */
|
|
||||||
// get window(): Window {
|
|
||||||
// return this.document.defaultView;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ngOnInit() {
|
|
||||||
// // this.window.location.href = '...';
|
|
||||||
// if (typeof document !== 'undefined') {
|
|
||||||
// this.window.open('https://'+(properties.environment == "beta" ? "beta." : "")+'search.marketplace.eosc-portal.eu/search/all?q=*', "_self");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import {ChangeDetectorRef, Component, Inject, ViewChild} from '@angular/core';
|
|
||||||
import {Subscription, zip} from 'rxjs';
|
|
||||||
import {ActivatedRoute, Router} from '@angular/router';
|
|
||||||
import {DOCUMENT, Location} from '@angular/common';
|
|
||||||
import {Meta, Title} from '@angular/platform-browser';
|
import {Meta, Title} from '@angular/platform-browser';
|
||||||
import {ConfigurationService} from '../openaireLibrary/utils/configuration/configuration.service';
|
import {ConfigurationService} from '../openaireLibrary/utils/configuration/configuration.service';
|
||||||
import {SearchDataprovidersService} from '../openaireLibrary/services/searchDataproviders.service';
|
|
||||||
import {SearchProjectsService} from '../openaireLibrary/services/searchProjects.service';
|
|
||||||
import {SearchOrganizationsService} from '../openaireLibrary/services/searchOrganizations.service';
|
|
||||||
import {RefineFieldResultsService} from '../openaireLibrary/services/refineFieldResults.service';
|
|
||||||
import {OpenaireEntities, SearchFields} from '../openaireLibrary/utils/properties/searchFields';
|
import {OpenaireEntities, SearchFields} from '../openaireLibrary/utils/properties/searchFields';
|
||||||
|
|
||||||
import {RouterHelper} from '../openaireLibrary/utils/routerHelper.class';
|
import {RouterHelper} from '../openaireLibrary/utils/routerHelper.class';
|
||||||
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
|
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
|
||||||
import {ErrorCodes} from '../openaireLibrary/utils/properties/errorCodes';
|
import {ErrorCodes} from '../openaireLibrary/utils/properties/errorCodes';
|
||||||
import {PiwikService} from '../openaireLibrary/utils/piwik/piwik.service';
|
import {PiwikService} from '../openaireLibrary/utils/piwik/piwik.service';
|
||||||
import {SEOService} from '../openaireLibrary/sharedComponents/SEO/SEO.service';
|
import {SEOService} from '../openaireLibrary/sharedComponents/SEO/SEO.service';
|
||||||
import {SearchResearchResultsService} from "../openaireLibrary/services/searchResearchResults.service";
|
|
||||||
import {HelperService} from "../openaireLibrary/utils/helper/helper.service";
|
import {HelperService} from "../openaireLibrary/utils/helper/helper.service";
|
||||||
import {Filter} from "../openaireLibrary/searchPages/searchUtils/searchHelperClasses.class";
|
import {Filter} from "../openaireLibrary/searchPages/searchUtils/searchHelperClasses.class";
|
||||||
import {AggregatorInfo, PortalAggregators} from "../utils/aggregators";
|
import {AggregatorInfo, PortalAggregators} from "../utils/aggregators";
|
||||||
import {SearchCustomFilter} from "../openaireLibrary/searchPages/searchUtils/searchUtils.class";
|
import {SearchCustomFilter} from "../openaireLibrary/searchPages/searchUtils/searchUtils.class";
|
||||||
import {properties} from "../../environments/environment";
|
import {properties} from "../../environments/environment";
|
||||||
import {portalProperties} from "../../environments/environment-aggregator";
|
import {portalProperties} from "../../environments/environment-aggregator";
|
||||||
|
import {UserManagementService} from '../openaireLibrary/services/user-management.service';
|
||||||
|
import {User} from '../openaireLibrary/login/utils/helper.class';
|
||||||
|
import {Identifier} from '../openaireLibrary/utils/string-utils.class';
|
||||||
|
import {RecommendationsService} from '../openaireLibrary/recommendations/recommendations.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'home',
|
selector: 'home',
|
||||||
|
@ -63,7 +26,6 @@ import {portalProperties} from "../../environments/environment-aggregator";
|
||||||
})
|
})
|
||||||
export class HomeComponent {
|
export class HomeComponent {
|
||||||
public keyword:string = "";
|
public keyword:string = "";
|
||||||
|
|
||||||
public searchFields:SearchFields = new SearchFields();
|
public searchFields:SearchFields = new SearchFields();
|
||||||
public errorCodes:ErrorCodes = new ErrorCodes();
|
public errorCodes:ErrorCodes = new ErrorCodes();
|
||||||
public routerHelper:RouterHelper = new RouterHelper();
|
public routerHelper:RouterHelper = new RouterHelper();
|
||||||
|
@ -76,12 +38,8 @@ export class HomeComponent {
|
||||||
showDataProviders: boolean = portalProperties.entities.datasource.isEnabled;
|
showDataProviders: boolean = portalProperties.entities.datasource.isEnabled;
|
||||||
properties: EnvProperties = properties;
|
properties: EnvProperties = properties;
|
||||||
public readMore: boolean = false;
|
public readMore: boolean = false;
|
||||||
|
|
||||||
private noOfFunders = 3;
|
|
||||||
public funders = [];
|
public funders = [];
|
||||||
|
|
||||||
subs: Subscription[] = [];
|
subs: Subscription[] = [];
|
||||||
|
|
||||||
resultsQuickFilter: { filter: Filter, selected: boolean, filterId: string, value: string } = {
|
resultsQuickFilter: { filter: Filter, selected: boolean, filterId: string, value: string } = {
|
||||||
filter: null,
|
filter: null,
|
||||||
selected: true,
|
selected: true,
|
||||||
|
@ -96,36 +54,27 @@ export class HomeComponent {
|
||||||
public pageContents = null;
|
public pageContents = null;
|
||||||
customFilter:SearchCustomFilter= null;
|
customFilter:SearchCustomFilter= null;
|
||||||
aggregator:AggregatorInfo;
|
aggregator:AggregatorInfo;
|
||||||
|
user: User;
|
||||||
|
recommendations;
|
||||||
|
resultsSize: number = 6;
|
||||||
|
errorMessage: string;
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private route: ActivatedRoute,
|
|
||||||
private _router: Router,
|
private _router: Router,
|
||||||
private _searchResearchResultsService: SearchResearchResultsService,
|
private _piwikService:PiwikService,
|
||||||
private _searchDataprovidersService: SearchDataprovidersService,
|
|
||||||
private _searchProjectsService: SearchProjectsService,
|
|
||||||
private _searchOrganizationsService: SearchOrganizationsService,
|
|
||||||
private _refineFieldResultsService:RefineFieldResultsService,
|
|
||||||
private location: Location, private _piwikService:PiwikService,
|
|
||||||
private config: ConfigurationService, private _meta: Meta, private _title: Title, private seoService: SEOService,
|
private config: ConfigurationService, private _meta: Meta, private _title: Title, private seoService: SEOService,
|
||||||
private helper: HelperService, private cdr: ChangeDetectorRef
|
private helper: HelperService, private cdr: ChangeDetectorRef,
|
||||||
|
private userManagementService: UserManagementService,
|
||||||
|
private recommendationsService: RecommendationsService
|
||||||
) {
|
) {
|
||||||
this.aggregator = PortalAggregators.eoscInfo;
|
this.aggregator = PortalAggregators.eoscInfo;
|
||||||
this.customFilter = PortalAggregators.getSearchCustomFilterByAggregator();
|
this.customFilter = PortalAggregators.getSearchCustomFilterByAggregator();
|
||||||
let description = "RDGraph Portal: Over 100M of research deduplicated, 170K research software, 11M research data. One of the largest open scholarly records collection worldwide.";
|
let description = "RDGraph Portal: Over 100M of research deduplicated, 170K research software, 11M research data. One of the largest open scholarly records collection worldwide.";
|
||||||
let title = "RDGraph Portal";
|
let title = "RDGraph Portal";
|
||||||
|
|
||||||
this._title.setTitle(title);
|
this._title.setTitle(title);
|
||||||
this._meta.updateTag({content:description},"name='description'");
|
this._meta.updateTag({content:description},"name='description'");
|
||||||
this._meta.updateTag({content:description},"property='og:description'");
|
this._meta.updateTag({content:description},"property='og:description'");
|
||||||
this._meta.updateTag({content:title},"property='og:title'");
|
this._meta.updateTag({content:title},"property='og:title'");
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private getPageContents() {
|
|
||||||
this.subs.push(this.helper.getPageHelpContents(this.properties, 'faircore4eosc', this._router.url).subscribe(contents => {
|
|
||||||
this.pageContents = contents;
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ceil(num: number) {
|
public ceil(num: number) {
|
||||||
|
@ -134,7 +83,12 @@ export class HomeComponent {
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
this.seoService.createLinkForCanonicalURL(this.properties.domain + this.properties.baseLink+this._router.url, false);
|
this.seoService.createLinkForCanonicalURL(this.properties.domain + this.properties.baseLink+this._router.url, false);
|
||||||
//this.getPageContents();
|
this.subs.push(this.userManagementService.getUserInfo().subscribe(user => {
|
||||||
|
this.user = user;
|
||||||
|
if (this.user?.orcid) {
|
||||||
|
this.getOrcidRecommendations();
|
||||||
|
}
|
||||||
|
}));
|
||||||
if(this.properties!=null){
|
if(this.properties!=null){
|
||||||
var url = this.properties.domain + this.properties.baseLink+this._router.url;
|
var url = this.properties.domain + this.properties.baseLink+this._router.url;
|
||||||
this._meta.updateTag({content:url},"property='og:url'");
|
this._meta.updateTag({content:url},"property='og:url'");
|
||||||
|
@ -142,7 +96,6 @@ export class HomeComponent {
|
||||||
this.subs.push(this._piwikService.trackView(this.properties, "RDGraph Portal").subscribe());
|
this.subs.push(this._piwikService.trackView(this.properties, "RDGraph Portal").subscribe());
|
||||||
}
|
}
|
||||||
|
|
||||||
//this.config.getCommunityInformation(this.properties, this.properties.adminToolsCommunity ).subscribe(data => {
|
|
||||||
this.subs.push(this.config.portalAsObservable.subscribe(data => {
|
this.subs.push(this.config.portalAsObservable.subscribe(data => {
|
||||||
if(data) {
|
if(data) {
|
||||||
var showEntity = {};
|
var showEntity = {};
|
||||||
|
@ -176,8 +129,8 @@ export class HomeComponent {
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnDestroy() {
|
public ngOnDestroy() {
|
||||||
for (let sub of this.subs) {
|
for (let sub of this.subs) {
|
||||||
sub.unsubscribe();
|
sub.unsubscribe();
|
||||||
|
@ -187,37 +140,20 @@ export class HomeComponent {
|
||||||
private handleError(message: string, error) {
|
private handleError(message: string, error) {
|
||||||
console.error("Home Page: "+message, error);
|
console.error("Home Page: "+message, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
entityChanged($event){
|
entityChanged($event){
|
||||||
this.selectedEntity = $event.entity;
|
this.selectedEntity = $event.entity;
|
||||||
this.selectedEntitySimpleUrl = $event.simpleUrl;
|
this.selectedEntitySimpleUrl = $event.simpleUrl;
|
||||||
this.selectedEntityAdvancedUrl = $event.advancedUrl;
|
this.selectedEntityAdvancedUrl = $event.advancedUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
goTo() {
|
goTo() {
|
||||||
let parameterNames = [];
|
let parameterNames = [];
|
||||||
let parameterValues = [];
|
let parameterValues = [];
|
||||||
// if (this.selectedEntity == "result") {
|
|
||||||
// if (this.resultTypes) {
|
|
||||||
// let values = [];
|
|
||||||
// for (let value of this.resultTypes.values) {
|
|
||||||
// if (value.selected) {
|
|
||||||
// values.push(value.id);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (values.length > 0 && values.length != 4) {
|
|
||||||
// parameterNames.push("type");
|
|
||||||
// parameterValues.push(values.join(","));
|
|
||||||
// }
|
|
||||||
// if (this.resultsQuickFilter && this.resultsQuickFilter.selected) {
|
|
||||||
// parameterNames.push(this.resultsQuickFilter.filterId);
|
|
||||||
// parameterValues.push('"' + encodeURIComponent(this.resultsQuickFilter.value) + '"');
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else if (this.selectedEntity == "all") {
|
|
||||||
if (this.resultsQuickFilter && this.resultsQuickFilter.selected) {
|
if (this.resultsQuickFilter && this.resultsQuickFilter.selected) {
|
||||||
parameterNames.push(this.resultsQuickFilter.filterId);
|
parameterNames.push(this.resultsQuickFilter.filterId);
|
||||||
parameterValues.push('"' + encodeURIComponent(this.resultsQuickFilter.value) + '"');
|
parameterValues.push('"' + encodeURIComponent(this.resultsQuickFilter.value) + '"');
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
if (this.keyword.length > 0) {
|
if (this.keyword.length > 0) {
|
||||||
parameterNames.push("fv0");
|
parameterNames.push("fv0");
|
||||||
parameterValues.push(this.keyword);
|
parameterValues.push(this.keyword);
|
||||||
|
@ -239,7 +175,7 @@ export class HomeComponent {
|
||||||
params["f0"] = "q";
|
params["f0"] = "q";
|
||||||
}
|
}
|
||||||
if(this.customFilter){
|
if(this.customFilter){
|
||||||
params = this.customFilter.getParameters(params);
|
params = this.customFilter.getParameters(params);
|
||||||
}
|
}
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
@ -259,4 +195,29 @@ export class HomeComponent {
|
||||||
this.disableSelect = event;
|
this.disableSelect = event;
|
||||||
this.cdr.detectChanges();
|
this.cdr.detectChanges();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
logIn() {
|
||||||
|
this.userManagementService.login();
|
||||||
|
}
|
||||||
|
|
||||||
|
logOut() {
|
||||||
|
this.userManagementService.logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
getOrcidRecommendations() {
|
||||||
|
let orcid = Identifier.getRawORCID(this.user.orcid);
|
||||||
|
this.subs.push(this.recommendationsService.getRecommendationsForOrcid(this.properties.recommendationsForOrcidAPI, orcid).subscribe(data => {
|
||||||
|
this.recommendations = data['recommendations'];
|
||||||
|
}, error => {
|
||||||
|
console.log(error);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
resultsSlider(results) {
|
||||||
|
let slider = [];
|
||||||
|
for (let i = 0; i < (results.length / this.resultsSize); i++) {
|
||||||
|
slider.push(results.slice(i * this.resultsSize, ((i + 1) * this.resultsSize)));
|
||||||
|
}
|
||||||
|
return slider;
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,11 +24,13 @@ import {EntitiesSelectionModule} from "../openaireLibrary/searchPages/searchUtil
|
||||||
import {QuickSelectionsModule} from "../openaireLibrary/searchPages/searchUtils/quick-selections.module";
|
import {QuickSelectionsModule} from "../openaireLibrary/searchPages/searchUtils/quick-selections.module";
|
||||||
import {IconsModule} from "../openaireLibrary/utils/icons/icons.module";
|
import {IconsModule} from "../openaireLibrary/utils/icons/icons.module";
|
||||||
import {IconsService} from "../openaireLibrary/utils/icons/icons.service";
|
import {IconsService} from "../openaireLibrary/utils/icons/icons.service";
|
||||||
import {book, cog, database, earth} from "../openaireLibrary/utils/icons/icons";
|
import {book, cog, database, earth, recommendations} from "../openaireLibrary/utils/icons/icons";
|
||||||
import {NumbersModule} from "../openaireLibrary/sharedComponents/numbers/numbers.module";
|
import {NumbersModule} from "../openaireLibrary/sharedComponents/numbers/numbers.module";
|
||||||
import {AdvancedSearchInputModule} from "../openaireLibrary/sharedComponents/advanced-search-input/advanced-search-input.module";
|
import {AdvancedSearchInputModule} from "../openaireLibrary/sharedComponents/advanced-search-input/advanced-search-input.module";
|
||||||
import {InputModule} from "../openaireLibrary/sharedComponents/input/input.module";
|
import {InputModule} from "../openaireLibrary/sharedComponents/input/input.module";
|
||||||
import {SearchInputModule} from "../openaireLibrary/sharedComponents/search-input/search-input.module";
|
import {SearchInputModule} from "../openaireLibrary/sharedComponents/search-input/search-input.module";
|
||||||
|
import {RecommendationsService} from '../openaireLibrary/recommendations/recommendations.service';
|
||||||
|
import {RecommendationCardModule} from '../openaireLibrary/recommendations/recommendation-card.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -41,13 +43,14 @@ import {SearchInputModule} from "../openaireLibrary/sharedComponents/search-inpu
|
||||||
HomeRoutingModule,
|
HomeRoutingModule,
|
||||||
HelperModule,
|
HelperModule,
|
||||||
ErrorMessagesModule,
|
ErrorMessagesModule,
|
||||||
SEOServiceModule, EntitiesSelectionModule, QuickSelectionsModule, IconsModule, NumbersModule, AdvancedSearchInputModule, InputModule, SearchInputModule
|
SEOServiceModule, EntitiesSelectionModule, QuickSelectionsModule, IconsModule, NumbersModule, AdvancedSearchInputModule, InputModule, SearchInputModule,
|
||||||
|
RecommendationCardModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
HomeComponent
|
HomeComponent
|
||||||
],
|
],
|
||||||
providers:[
|
providers:[
|
||||||
PreviousRouteRecorder
|
PreviousRouteRecorder, RecommendationsService
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
HomeComponent
|
HomeComponent
|
||||||
|
@ -55,6 +58,6 @@ import {SearchInputModule} from "../openaireLibrary/sharedComponents/search-inpu
|
||||||
})
|
})
|
||||||
export class HomeModule {
|
export class HomeModule {
|
||||||
constructor(private iconsService: IconsService) {
|
constructor(private iconsService: IconsService) {
|
||||||
this.iconsService.registerIcons([book, earth, cog, database]);
|
this.iconsService.registerIcons([book, earth, cog, database, recommendations]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {PreviousRouteRecorder} from '../../openaireLibrary/utils/piwik/previousR
|
||||||
import {OrpRoutingModule} from './orp-routing.module';
|
import {OrpRoutingModule} from './orp-routing.module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [ResultLandingModule, OrpRoutingModule],
|
imports: [OrpRoutingModule, ResultLandingModule],
|
||||||
declarations:[OpenaireOrpComponent],
|
declarations:[OpenaireOrpComponent],
|
||||||
providers:[FreeGuard, PreviousRouteRecorder],
|
providers:[FreeGuard, PreviousRouteRecorder],
|
||||||
exports:[OpenaireOrpComponent]
|
exports:[OpenaireOrpComponent]
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import {NgModule} from '@angular/core';
|
||||||
|
import {RouterModule} from '@angular/router';
|
||||||
|
import {NaturalLanguageSearchComponent} from './natural-language-search.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forChild([
|
||||||
|
{
|
||||||
|
path: '', component: NaturalLanguageSearchComponent,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class NaturalLanguageSearchModuleRoutingModule { }
|
|
@ -0,0 +1,92 @@
|
||||||
|
<div class="uk-section uk-container uk-container-large" uk-scrollspy="target: [uk-scrollspy-class]; cls: uk-animation-slide-bottom-medium; delay: 200">
|
||||||
|
<div class="uk-flex uk-flex-column uk-flex-middle">
|
||||||
|
<div class="uk-text-center">
|
||||||
|
<h1 class="uk-h3 uk-margin-remove" uk-scrollspy-class>
|
||||||
|
Natural search, real results.
|
||||||
|
</h1>
|
||||||
|
<p class="uk-h6 uk-margin-top uk-margin-medium-bottom" uk-scrollspy-class>
|
||||||
|
Search as you speak. Intuitive, natural, effortless.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="uk-width-1-2@m uk-width-1-1" uk-scrollspy-class>
|
||||||
|
<div search-input [(value)]="phrase" (searchEmitter)="search()"
|
||||||
|
[placeholder]="'Search in natural language'"
|
||||||
|
[searchInputClass]="'flat background'">
|
||||||
|
</div>
|
||||||
|
<div *ngIf="queryPhrase" class="uk-text-center uk-text-small uk-margin-top">
|
||||||
|
<span class="uk-text-warning">
|
||||||
|
Note: Each new question deletes the previous session
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-container *ngIf="queryPhrase">
|
||||||
|
<div *ngIf="showLoading">
|
||||||
|
<div class="uk-section">
|
||||||
|
<loading></loading>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="!showLoading">
|
||||||
|
<div class="uk-section">
|
||||||
|
<ng-container *ngIf="errorMessage">
|
||||||
|
<div class="uk-flex uk-flex-middle uk-margin-bottom">
|
||||||
|
<img src="assets/common-assets/common/Logo_Small.png" alt="OpenAIRE" loading="lazy"
|
||||||
|
class="bot-img">
|
||||||
|
<span class="uk-text-small uk-text-bolder uk-margin-small-left">
|
||||||
|
Bot
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{errorMessage}}
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="results && results.length == 0">
|
||||||
|
<div class="uk-flex uk-flex-middle uk-margin-bottom">
|
||||||
|
<img src="assets/common-assets/common/Logo_Small.png" alt="OpenAIRE" loading="lazy"
|
||||||
|
class="bot-img">
|
||||||
|
<span class="uk-text-small uk-text-bolder uk-margin-small-left">
|
||||||
|
Bot
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
No results found for your query
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="results && results.data">
|
||||||
|
<div class="uk-margin-medium-bottom">
|
||||||
|
<div class="uk-flex uk-flex-middle uk-margin-small-bottom">
|
||||||
|
<img src="assets/common-assets/common/Logo_Small.png" alt="OpenAIRE" loading="lazy"
|
||||||
|
class="bot-img">
|
||||||
|
<span class="uk-text-small uk-text-bolder uk-margin-small-left">
|
||||||
|
Bot
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<table class="uk-table uk-table-striped uk-table-small uk-table-responsive">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<ng-container *ngFor="let header of results.columns; let i = index;">
|
||||||
|
<th *ngIf="i != indexColumnId">
|
||||||
|
{{header}}
|
||||||
|
</th>
|
||||||
|
</ng-container>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr *ngFor="let row of results.data">
|
||||||
|
<ng-container *ngFor="let item of row; let i = index;">
|
||||||
|
<td *ngIf="i != indexColumnId">
|
||||||
|
{{item}}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
|
@ -0,0 +1,3 @@
|
||||||
|
.bot-img {
|
||||||
|
width: 30px;
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
import {Component} from "@angular/core";
|
||||||
|
import {Subscriber} from "rxjs";
|
||||||
|
import {NaturalLanguageSearchService} from "./natural-language-search.service";
|
||||||
|
import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties";
|
||||||
|
import {properties} from "../../environments/environment";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'natural-language-search',
|
||||||
|
templateUrl: './natural-language-search.component.html',
|
||||||
|
styleUrls: ['natural-language-search.component.less']
|
||||||
|
})
|
||||||
|
|
||||||
|
export class NaturalLanguageSearchComponent {
|
||||||
|
private subscriptions = [];
|
||||||
|
properties: EnvProperties = properties;
|
||||||
|
showLoading: boolean = false;
|
||||||
|
errorMessage: string;
|
||||||
|
|
||||||
|
phrase: string;
|
||||||
|
queryPhrase: string;
|
||||||
|
results;
|
||||||
|
indexColumnId: number;
|
||||||
|
|
||||||
|
constructor(private naturalLanguageSearchService: NaturalLanguageSearchService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.subscriptions.forEach(subscription => {
|
||||||
|
if (subscription instanceof Subscriber) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
search() {
|
||||||
|
this.results = null;
|
||||||
|
this.queryPhrase = this.phrase;
|
||||||
|
this.errorMessage = null;
|
||||||
|
this.showLoading = true;
|
||||||
|
this.subscriptions.push(this.naturalLanguageSearchService.getResults(this.properties.naturalLanguageSearchAPI, this.queryPhrase).subscribe(data => {
|
||||||
|
if(data && data['data'] && data['data'].length > 0) {
|
||||||
|
if(data && data['columns']) {
|
||||||
|
for(let i = 0; i < data['columns'].length - 1; i++) {
|
||||||
|
if(data['columns'][i] == 'id') {
|
||||||
|
this.indexColumnId = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.results = data;
|
||||||
|
} else {
|
||||||
|
this.results = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showLoading = false;
|
||||||
|
}, error => {
|
||||||
|
if(error.status == 500) {
|
||||||
|
this.errorMessage = error.error.message;
|
||||||
|
} else {
|
||||||
|
this.errorMessage = 'Sorry, something went wrong. Please try again later.';
|
||||||
|
}
|
||||||
|
this.showLoading = false;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
import {NgModule} from "@angular/core";
|
||||||
|
import {CommonModule} from "@angular/common";
|
||||||
|
import {RouterModule} from "@angular/router";
|
||||||
|
import {SearchInputModule} from "../openaireLibrary/sharedComponents/search-input/search-input.module";
|
||||||
|
import {IconsModule} from "../openaireLibrary/utils/icons/icons.module";
|
||||||
|
import {LoadingModule} from "../openaireLibrary/utils/loading/loading.module";
|
||||||
|
import {NaturalLanguageSearchModuleRoutingModule} from "./natural-language-search-routing.module";
|
||||||
|
import {NaturalLanguageSearchComponent} from "./natural-language-search.component";
|
||||||
|
import {NaturalLanguageSearchService} from "./natural-language-search.service";
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
NaturalLanguageSearchModuleRoutingModule, CommonModule, RouterModule, IconsModule,
|
||||||
|
SearchInputModule, LoadingModule
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
NaturalLanguageSearchComponent
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
NaturalLanguageSearchService
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
NaturalLanguageSearchComponent
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
export class NaturalLanguageSearchModule {
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
import {HttpClient, HttpHeaders} from "@angular/common/http";
|
||||||
|
import {Injectable} from "@angular/core";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
|
||||||
|
export class NaturalLanguageSearchService {
|
||||||
|
constructor(private http: HttpClient) {
|
||||||
|
}
|
||||||
|
|
||||||
|
getResults(url: string, queryPhrase: string) {
|
||||||
|
const body = {
|
||||||
|
"nl_query": queryPhrase,
|
||||||
|
};
|
||||||
|
const options = {
|
||||||
|
headers: new HttpHeaders({
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
})
|
||||||
|
};
|
||||||
|
return this.http.post(url, body, options);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1 @@
|
||||||
Subproject commit 13daf1b5d4fc67b518df5c11d07c78eb85f85692
|
Subproject commit 25b3c6121b00b18f482b08ad9d7bf1199cb63a9a
|
|
@ -0,0 +1,84 @@
|
||||||
|
<ng-container *ngIf="showLoading">
|
||||||
|
<div class="uk-container uk-container-large uk-section">
|
||||||
|
<loading></loading>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="!showLoading && communities?.length">
|
||||||
|
<div class="uk-flex uk-background-default" [class.uk-flex-column]="isMobile">
|
||||||
|
<aside [attr.offset]="offset" class="sidebar uk-background-default uk-visible@m" uk-sticky>
|
||||||
|
<div class="uk-padding">
|
||||||
|
<div class="uk-text-center">
|
||||||
|
<h5>In which community are you interested?</h5>
|
||||||
|
<p>Select a community to see recommendations.</p>
|
||||||
|
<div *ngIf="filteredCommunities?.length >= size" search-input [searchControl]="keywordControl"
|
||||||
|
[placeholder]="'Search for communities'"
|
||||||
|
[searchInputClass]="'flat background'">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="uk-margin-medium-top">
|
||||||
|
<div *ngIf="filteredCommunities?.length">
|
||||||
|
<span class="uk-text-bold uk-text-meta uk-text-uppercase">Communities</span>
|
||||||
|
<ul class="uk-list uk-list-divider">
|
||||||
|
<li *ngFor="let community of filteredCommunities;" class="uk-padding-xsmall" [class.uk-active-custom]="activeCommunity == community.communityId">
|
||||||
|
<a class="uk-link-heading uk-text-bold" (click)="selectCommunity(community.communityId); setActiveCommunity(community.communityId);">
|
||||||
|
{{community.title}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="filteredCommunities?.length == 0" class="uk-text-center uk-text-bold uk-text-meta">
|
||||||
|
No communities found based on your keyword
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
<div class="uk-hidden@m">
|
||||||
|
<div class="uk-padding-small">
|
||||||
|
<div class="uk-text-center">
|
||||||
|
<h5>In which community are you interested?</h5>
|
||||||
|
<p>Select a community to see recommendations.</p>
|
||||||
|
<div *ngIf="filteredCommunities?.length >= size" search-input [searchControl]="keywordControl"
|
||||||
|
[placeholder]="'Search for communities'"
|
||||||
|
[searchInputClass]="'flat background'">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="uk-margin-top">
|
||||||
|
<div *ngIf="filteredCommunities?.length">
|
||||||
|
<span class="uk-text-bold uk-text-meta uk-text-uppercase">Communities</span>
|
||||||
|
<ul class="uk-list uk-list-divider">
|
||||||
|
<li *ngFor="let community of filteredCommunities;" class="uk-padding-xsmall" [class.uk-active-custom]="activeCommunity == community.communityId">
|
||||||
|
<a class="uk-link-heading uk-text-bold" (click)="selectCommunity(community.communityId); setActiveCommunity(community.communityId); scrollToId('content');">
|
||||||
|
{{community.title}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="filteredCommunities?.length == 0" class="uk-text-center uk-text-bold uk-text-meta">
|
||||||
|
No communities found based on your keyword
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="content" class="content uk-width-expand uk-container">
|
||||||
|
<div *ngIf="errorMessage" class="uk-padding uk-text-center" [class.uk-position-center]="!isMobile">
|
||||||
|
<h4 class="uk-text-warning uk-width-1-1 uk-width-2-3@m uk-margin-auto">{{errorMessage}}</h4>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="!recommendations && !errorMessage" class="uk-padding uk-text-center" [class.uk-position-center]="!isMobile">
|
||||||
|
<h3 class="uk-width-1-1 uk-width-2-3@m uk-margin-auto">Select a community from the list on the left and receive recommendations.</h3>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="recommendations" class="uk-section">
|
||||||
|
<div *ngFor="let item of recommendations" class="uk-margin-large-bottom">
|
||||||
|
<div class="uk-flex uk-flex-middle uk-margin-medium-bottom">
|
||||||
|
<icon [name]="'recommendations'" [ratio]="1.5" [flex]="true"></icon>
|
||||||
|
<span class="uk-margin-left">Recommended by topic <span class="uk-text-bold">{{item.field}}</span></span>
|
||||||
|
</div>
|
||||||
|
<div class="uk-grid uk-child-width-1-2@m uk-child-width-1-3@l" uk-height-match=".uk-card" uk-grid>
|
||||||
|
<div *ngFor="let result of item.recommendations">
|
||||||
|
<recommendation-card [result]="result" [category]="item" [community]="activeCommunity" [user]="user"></recommendation-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
|
@ -0,0 +1,30 @@
|
||||||
|
@import (less) "~src/assets/openaire-theme/less/color.less";
|
||||||
|
|
||||||
|
@header-height: var(--header-height);
|
||||||
|
@sidebar-width: 450px;
|
||||||
|
|
||||||
|
.sidebar, .content {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
height: calc(100vh - @header-height);
|
||||||
|
width: @sidebar-width;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
background-color: @default-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uk-active-custom {
|
||||||
|
background-color: @ciel-color;
|
||||||
|
position: relative;
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
font-size: 1.8em;
|
||||||
|
font-family: "Material Icons";
|
||||||
|
content: "\e5cc"; /* chevron right */
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
import {ChangeDetectorRef, Component} from "@angular/core";
|
||||||
|
import {CommunitiesService} from "../../openaireLibrary/connect/communities/communities.service";
|
||||||
|
import {EnvProperties} from "../../openaireLibrary/utils/properties/env-properties";
|
||||||
|
import {properties} from "../../../environments/environment";
|
||||||
|
import {CommunityInfo} from "../../openaireLibrary/connect/community/communityInfo";
|
||||||
|
import {Subscriber, zip} from "rxjs";
|
||||||
|
import {FormBuilder, FormControl} from "@angular/forms";
|
||||||
|
import {debounceTime, distinctUntilChanged} from "rxjs/operators";
|
||||||
|
import {RecommendationsService} from "../../openaireLibrary/recommendations/recommendations.service";
|
||||||
|
import {ActivatedRoute, Router} from "@angular/router";
|
||||||
|
import {UserManagementService} from "../../openaireLibrary/services/user-management.service";
|
||||||
|
import {User} from "../../openaireLibrary/login/utils/helper.class";
|
||||||
|
import {LayoutService} from "../../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
|
||||||
|
import {HelperFunctions} from "../../openaireLibrary/utils/HelperFunctions.class";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'category-to-item',
|
||||||
|
templateUrl: './category-to-item.component.html',
|
||||||
|
styleUrls: ['category-to-item.component.less']
|
||||||
|
})
|
||||||
|
|
||||||
|
export class CategoryToItemComponent {
|
||||||
|
private subscriptions = [];
|
||||||
|
properties: EnvProperties = properties;
|
||||||
|
|
||||||
|
showLoading: boolean = true;
|
||||||
|
errorMessage: string;
|
||||||
|
offset: number;
|
||||||
|
|
||||||
|
activeCommunity: string;
|
||||||
|
size: number = 5; // show search-bar only when communities are more than this number - defaults to 5
|
||||||
|
communities: CommunityInfo[];
|
||||||
|
filteredCommunities: CommunityInfo[];
|
||||||
|
recommendations: any;
|
||||||
|
user: User;
|
||||||
|
|
||||||
|
keywordControl: FormControl;
|
||||||
|
keyword: string;
|
||||||
|
|
||||||
|
isMobile: boolean;
|
||||||
|
|
||||||
|
constructor(private communitiesService: CommunitiesService,
|
||||||
|
private recommendationsService: RecommendationsService,
|
||||||
|
private router: Router,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private fb: FormBuilder,
|
||||||
|
private cdr: ChangeDetectorRef,
|
||||||
|
private userManagementService: UserManagementService,
|
||||||
|
private layoutService: LayoutService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.properties = properties;
|
||||||
|
if (typeof document !== "undefined") {
|
||||||
|
this.offset = Number.parseInt(getComputedStyle(document.documentElement).getPropertyValue('--header-height'));
|
||||||
|
}
|
||||||
|
this.layoutService.isMobile.subscribe(isMobile => {
|
||||||
|
this.isMobile = isMobile;
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
});
|
||||||
|
this.getCommunities();
|
||||||
|
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
|
||||||
|
this.user = user;
|
||||||
|
}));
|
||||||
|
this.subscriptions.push(this.route.params.subscribe(params => {
|
||||||
|
if(params && params['community']) {
|
||||||
|
this.subscriptions.push(this.recommendationsService.getRecommendationsForCommunity(this.properties.recommendationsForCommunityAPI, params['community'], this.user ? this.user.id : null).subscribe(data => {
|
||||||
|
this.recommendations = data;
|
||||||
|
this.setActiveCommunity(params['community']);
|
||||||
|
}, error => {
|
||||||
|
if(error.status == 422) {
|
||||||
|
this.errorMessage = 'We could not find any recommendations for this community.'
|
||||||
|
} else {
|
||||||
|
this.errorMessage = 'Sorry, something went wrong.';
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
this.keywordControl = this.fb.control('');
|
||||||
|
this.subscriptions.push(this.keywordControl.valueChanges.pipe(debounceTime(300), distinctUntilChanged()).subscribe(value => {
|
||||||
|
this.keyword = value;
|
||||||
|
this.filtering();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.subscriptions.forEach(subscription => {
|
||||||
|
if (subscription instanceof Subscriber) {
|
||||||
|
subscription.unsubscribe();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getCommunities() {
|
||||||
|
this.subscriptions.push(zip(this.recommendationsService.getAvailableCommunities(this.properties.availableCommunitiesAPI), this.communitiesService.getCommunities(this.properties, this.properties.communitiesAPI)).subscribe(data => {
|
||||||
|
let availableCommunities: any = data[0];
|
||||||
|
this.communities = availableCommunities.map(id => {
|
||||||
|
const obj = data[1].find(o => o.communityId === id);
|
||||||
|
return { id, ...obj };
|
||||||
|
});
|
||||||
|
this.communities.sort((a, b) => a['title'].localeCompare(b['title']));
|
||||||
|
this.filteredCommunities = this.communities;
|
||||||
|
this.showLoading = false;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
filtering() {
|
||||||
|
let filteredCommunities = this.communities;
|
||||||
|
if(!this.keyword){
|
||||||
|
this.keyword = '';
|
||||||
|
}
|
||||||
|
if(this.communities.length) {
|
||||||
|
filteredCommunities = filteredCommunities.filter(item => (item['title'] && item['title'].toLowerCase().includes(this.keyword.toLowerCase())) || (item['shortTitle'] && item['shortTitle'].toLowerCase().includes(this.keyword.toLowerCase())));
|
||||||
|
}
|
||||||
|
this.filteredCommunities = filteredCommunities;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectCommunity(id: string) {
|
||||||
|
this.errorMessage = null;
|
||||||
|
this.router.navigate(['/recommendations/category-to-item/' + id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
setActiveCommunity(id) {
|
||||||
|
this.activeCommunity = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollToId(value: string) {
|
||||||
|
HelperFunctions.scrollToId(value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
import {NgModule} from '@angular/core';
|
||||||
|
import {RouterModule} from '@angular/router';
|
||||||
|
import {CategoryToItemComponent} from './category-to-item/category-to-item.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forChild([
|
||||||
|
{
|
||||||
|
path: 'category-to-item', component: CategoryToItemComponent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'category-to-item/:community', component: CategoryToItemComponent
|
||||||
|
}
|
||||||
|
])
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class RecommendationsRoutingModule { }
|
|
@ -0,0 +1,33 @@
|
||||||
|
import {NgModule} from "@angular/core";
|
||||||
|
import {CommonModule} from "@angular/common";
|
||||||
|
import {RouterModule} from "@angular/router";
|
||||||
|
import {CategoryToItemComponent} from "./category-to-item/category-to-item.component";
|
||||||
|
import {RecommendationsRoutingModule} from "./recommendations-routing.module";
|
||||||
|
import {SearchInputModule} from "../openaireLibrary/sharedComponents/search-input/search-input.module";
|
||||||
|
import {CommunitiesService} from "../openaireLibrary/connect/communities/communities.service";
|
||||||
|
import {IconsModule} from "../openaireLibrary/utils/icons/icons.module";
|
||||||
|
import {LoadingModule} from "../openaireLibrary/utils/loading/loading.module";
|
||||||
|
import {RecommendationsService} from "../openaireLibrary/recommendations/recommendations.service";
|
||||||
|
import {RecommendationCardModule} from "../openaireLibrary/recommendations/recommendation-card.module";
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RecommendationsRoutingModule, CommonModule, RouterModule, IconsModule,
|
||||||
|
SearchInputModule, LoadingModule, RecommendationCardModule
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
CategoryToItemComponent
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
CommunitiesService, RecommendationsService
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
CategoryToItemComponent
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
export class RecommendationsModule {
|
||||||
|
constructor() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,7 +35,7 @@ export class AggregatorInfo {
|
||||||
export class PortalAggregators {
|
export class PortalAggregators {
|
||||||
static eoscInfo: AggregatorInfo =
|
static eoscInfo: AggregatorInfo =
|
||||||
new AggregatorInfo("faircore4eosc", "Faircore4eosc Explore", "assets/logo.svg",
|
new AggregatorInfo("faircore4eosc", "Faircore4eosc Explore", "assets/logo.svg",
|
||||||
null, null, null, null,null,null ,false,true,
|
null, null, null, null,null,null ,true,true,
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -168,6 +168,10 @@
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.author-recommendations hr {
|
||||||
|
border-top: 1px solid @grey-color;
|
||||||
|
}
|
||||||
|
|
||||||
//.image-front-topbar, .search-form, #main-menu .uk-navbar-container, #main-menu-small .uk-navbar-container {
|
//.image-front-topbar, .search-form, #main-menu .uk-navbar-container, #main-menu-small .uk-navbar-container {
|
||||||
.eosc-explore-back-search-bar {
|
.eosc-explore-back-search-bar {
|
||||||
//background: @global-primary-background;
|
//background: @global-primary-background;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 165.67 142.95">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
.cls-1 {
|
||||||
|
stroke-width: 0px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<g id="Layer_1-2" data-name="Layer 1">
|
||||||
|
<g>
|
||||||
|
<path class="cls-1" d="m78.87,47.8c-7.25-.92-16.45,2.46-18.53,15-.18,1.09.55,2.12,1.64,2.3.11.02.22.03.33.03.96,0,1.81-.69,1.97-1.67,2.03-12.25,11.29-12.04,14.08-11.69.09.01.25.03.33.03,1.1,0,2-.9,2-2s-.8-1.91-1.82-2Zm0,0c-7.25-.92-16.45,2.46-18.53,15-.18,1.09.55,2.12,1.64,2.3.11.02.22.03.33.03.96,0,1.81-.69,1.97-1.67,2.03-12.25,11.29-12.04,14.08-11.69.09.01.25.03.33.03,1.1,0,2-.9,2-2s-.8-1.91-1.82-2Zm80.15,15.39c-41.4-21.33-39.11-30.98-48.51-46.48-6.71-11.06-11.35-14.09-13.45-14.92-.73-.29-1.42-.64-2.12-1-3.51-1.78-14.48-.06-17.77.52-.62.1-1.23.25-1.83.45-5.94,1.92-40.26,13.5-58.54,29.94C-3.27,49.73-.43,75.91,1.05,84.78c2.26,13.58,19.56,47.24,72.13,55.87,52.57,8.64,70.85-7.62,85.84-39.11,14.98-31.49,0-38.35,0-38.35Zm-116.89-15.36c-.06.13-9.43,5.27-9.43,5.27l3.91-10.92-7.43-7.68,11.04,1.14-.22-.03c.19-.25,4.86-10.16,4.86-10.16l2.38,11.02,10.64,1.21s-9.24,6.07-9.24,6.19c.19,0,2.31,11.84,2.31,11.84,0,0-8.63-7.88-8.82-7.88Zm37.27,68.26s-12.1-.57-12.38-.86c-.29-.29-4.67-2.19-5.34-6.95-.66-4.76,0-7.81,0-7.81l24.48,2.57s-.67,12.1-6.76,13.05Zm7.68-18.07c-1.51,2.02-24.37-2.22-24.37-2.22-.38-1.01-.64-5.39-2.42-9.2-1.78-3.81-15.11-17.4-3.68-35.05,11.42-17.65,31.81-9.91,31.81-9.91,0,0,18.03,7.24,16.88,22.99-1.14,15.74-7.42,19.67-9.2,21.33-.59.55-7.2,9.65-9.02,12.06Zm31.56,25.75s-8.62-7.87-8.83-7.87c-.06.12-9.43,5.27-9.43,5.27l3.91-10.92-7.43-7.69,11.05,1.15-.23-.03c.2-.26,4.86-10.16,4.86-10.16l2.38,11.01,10.64,1.21s-9.24,6.07-9.24,6.19c.19,0,2.32,11.84,2.32,11.84Zm13.58-33.14s-8.63-7.88-8.82-7.88c-.06.13-9.43,5.27-9.43,5.27l3.91-10.92-7.43-7.68,11.04,1.14-.22-.03c.19-.25,4.86-10.16,4.86-10.16l2.38,11.02,10.64,1.21s-9.24,6.07-9.24,6.19c.19,0,2.31,11.84,2.31,11.84Zm-53.35-42.83c-7.25-.92-16.45,2.46-18.53,15-.18,1.09.55,2.12,1.64,2.3.11.02.22.03.33.03.96,0,1.81-.69,1.97-1.67,2.03-12.25,11.29-12.04,14.08-11.69.09.01.25.03.33.03,1.1,0,2-.9,2-2s-.8-1.91-1.82-2Zm0,0c-7.25-.92-16.45,2.46-18.53,15-.18,1.09.55,2.12,1.64,2.3.11.02.22.03.33.03.96,0,1.81-.69,1.97-1.67,2.03-12.25,11.29-12.04,14.08-11.69.09.01.25.03.33.03,1.1,0,2-.9,2-2s-.8-1.91-1.82-2Zm0,0c-7.25-.92-16.45,2.46-18.53,15-.18,1.09.55,2.12,1.64,2.3.11.02.22.03.33.03.96,0,1.81-.69,1.97-1.67,2.03-12.25,11.29-12.04,14.08-11.69.09.01.25.03.33.03,1.1,0,2-.9,2-2s-.8-1.91-1.82-2Z"/>
|
||||||
|
<path class="cls-1" d="m80.69,49.8c0,1.1-.9,2-2,2-.08,0-.24-.02-.33-.03-2.79-.35-12.05-.56-14.08,11.69-.16.98-1.01,1.67-1.97,1.67-.11,0-.22-.01-.33-.03-1.09-.18-1.82-1.21-1.64-2.3,2.08-12.54,11.28-15.92,18.53-15,1.02.09,1.82.95,1.82,2Z"/>
|
||||||
|
<path class="cls-1" d="m80.69,49.8c0,1.1-.9,2-2,2-.08,0-.24-.02-.33-.03-2.79-.35-12.05-.56-14.08,11.69-.16.98-1.01,1.67-1.97,1.67-.11,0-.22-.01-.33-.03-1.09-.18-1.82-1.21-1.64-2.3,2.08-12.54,11.28-15.92,18.53-15,1.02.09,1.82.95,1.82,2Z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.0 KiB |
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 109.97 98.32">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
.cls-1 {
|
||||||
|
stroke-width: 0px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<g id="Layer_1-2" data-name="Layer 1">
|
||||||
|
<g>
|
||||||
|
<path class="cls-1" d="m10.83,10.16c.19-.25,4.86-10.16,4.86-10.16l2.38,11.02,10.63,1.21s-9.43,6.19-9.24,6.19,2.32,11.84,2.32,11.84c0,0-8.76-8-8.83-7.87s-9.43,5.27-9.43,5.27l3.9-10.92L0,9.05l11.05,1.14-.22-.03Z"/>
|
||||||
|
<path class="cls-1" d="m92.1,45.08c.19-.25,4.86-10.16,4.86-10.16l2.38,11.02,10.63,1.21s-9.43,6.19-9.24,6.19,2.32,11.84,2.32,11.84c0,0-8.76-8-8.83-7.87s-9.43,5.27-9.43,5.27l3.9-10.92-7.43-7.68,11.05,1.14-.22-.03Z"/>
|
||||||
|
<path class="cls-1" d="m78.51,78.22c.19-.25,4.86-10.16,4.86-10.16l2.38,11.02,10.63,1.21s-9.43,6.19-9.24,6.19,2.32,11.84,2.32,11.84c0,0-8.76-8-8.83-7.87s-9.43,5.27-9.43,5.27l3.9-10.92-7.43-7.68,11.05,1.14-.22-.03Z"/>
|
||||||
|
<path class="cls-1" d="m32.51,75.02l24.48,2.57s-.67,12.1-6.76,13.05c0,0-12.1-.57-12.38-.86s-4.67-2.19-5.33-6.95,0-7.81,0-7.81Z"/>
|
||||||
|
<path class="cls-1" d="m59.24,16.19s-20.38-7.74-31.81,9.91c-11.43,17.65,1.91,31.23,3.69,35.04,1.77,3.81,2.03,8.19,2.42,9.21,0,0,22.85,4.24,24.37,2.22,1.81-2.41,8.43-11.51,9.01-12.06,1.78-1.66,8.07-5.59,9.21-21.33,1.14-15.75-16.89-22.99-16.89-22.99Zm-9.72,10.15c-.09,0-.25-.01-.33-.02-2.79-.35-12.05-.56-14.08,11.69-.16.97-1.01,1.67-1.97,1.67-.11,0-.22-.01-.33-.03-1.09-.18-1.83-1.21-1.65-2.3,2.09-12.54,11.29-15.92,18.53-15,1.03.09,1.83.95,1.83,1.99,0,1.11-.9,2-2,2Z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 165.67 142.94">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
.cls-1 {
|
||||||
|
fill: #ffd215;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-1, .cls-2, .cls-3 {
|
||||||
|
stroke-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-2 {
|
||||||
|
fill: #e86438;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-3 {
|
||||||
|
fill: #f9f9f9;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<g id="Layer_1-2" data-name="Layer 1">
|
||||||
|
<g>
|
||||||
|
<path class="cls-2" d="m94.93.79c.7.35,1.39.71,2.12.99,2.1.83,6.74,3.86,13.45,14.93,9.4,15.49,7.11,25.14,48.51,46.48,0,0,14.98,6.86,0,38.35s-33.27,47.75-85.84,39.11C20.6,132.01,3.31,98.35,1.04,84.77c-1.48-8.86-4.32-35.05,15.75-53.08C35.08,15.26,69.4,3.67,75.33,1.75c.6-.19,1.21-.34,1.83-.45,3.29-.57,14.26-2.29,17.77-.51Z"/>
|
||||||
|
<path class="cls-1" d="m40,35.6c.19-.25,4.86-10.16,4.86-10.16l2.38,11.02,10.63,1.21s-9.43,6.19-9.24,6.19,2.32,11.84,2.32,11.84c0,0-8.76-8-8.83-7.87s-9.43,5.27-9.43,5.27l3.9-10.92-7.43-7.68,11.05,1.14"/>
|
||||||
|
<path class="cls-1" d="m121.27,70.52c.19-.25,4.86-10.16,4.86-10.16l2.38,11.02,10.63,1.21s-9.43,6.19-9.24,6.19,2.32,11.84,2.32,11.84c0,0-8.76-8-8.83-7.87s-9.43,5.27-9.43,5.27l3.9-10.92-7.43-7.68,11.05,1.14"/>
|
||||||
|
<path class="cls-1" d="m107.68,103.67c.19-.25,4.86-10.16,4.86-10.16l2.38,11.02,10.63,1.21s-9.43,6.19-9.24,6.19,2.32,11.84,2.32,11.84c0,0-8.76-8-8.83-7.87s-9.43,5.27-9.43,5.27l3.9-10.92-7.43-7.68,11.05,1.14"/>
|
||||||
|
<path class="cls-3" d="m61.68,100.46l24.48,2.57s-.67,12.1-6.76,13.05c0,0-12.1-.57-12.38-.86s-4.67-2.19-5.33-6.95,0-7.81,0-7.81Z"/>
|
||||||
|
<path class="cls-3" d="m62.7,95.79c-.38-1.02-.64-5.4-2.42-9.21s-15.11-17.4-3.68-35.05,31.81-9.9,31.81-9.9c0,0,18.03,7.24,16.89,22.98s-7.43,19.67-9.21,21.33c-.59.55-7.2,9.65-9.02,12.06-1.52,2.02-24.37-2.22-24.37-2.22Z"/>
|
||||||
|
<path class="cls-2" d="m62.3,65.12c-.11,0-.22,0-.33-.03-1.09-.18-1.83-1.21-1.65-2.3,2.08-12.55,11.28-15.92,18.53-15h0c1.02.09,1.82.95,1.82,1.99,0,1.1-.9,2-2,2-.08,0-.24-.01-.33-.02-2.79-.35-12.05-.56-14.08,11.69-.16.98-1.01,1.67-1.97,1.67Z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -25,7 +25,14 @@ let props: EnvProperties = {
|
||||||
searchLinkToServices: "/search/find/services",
|
searchLinkToServices: "/search/find/services",
|
||||||
searchLinkToAdvancedServices: "/search/advanced/services",
|
searchLinkToAdvancedServices: "/search/advanced/services",
|
||||||
reCaptchaSiteKey: null,
|
reCaptchaSiteKey: null,
|
||||||
footerGrantText : ""
|
footerGrantText : "",
|
||||||
|
|
||||||
|
naturalLanguageSearchAPI: "https://darelab.athenarc.gr/nl_search/api/fc4e_get_results/",
|
||||||
|
availableCommunitiesAPI: 'https://darelab.athenarc.gr/api/faircore/category-based-recommender/available-communities',
|
||||||
|
recommendationsForCommunityAPI: 'https://darelab.athenarc.gr/api/faircore/category-based-recommender/recommend',
|
||||||
|
recommendationsForOrcidAPI: 'https://darelab.athenarc.gr/api/faircore/user-to-item-recommender/recommend',
|
||||||
|
recommendationsForPublicationAPI: 'https://darelab.athenarc.gr/api/faircore/item-to-item-recommender/recommend/',
|
||||||
|
feedbackForRecommendationAPI: 'https://darelab.athenarc.gr/api/faircore/category-based-recommender/update/'
|
||||||
};
|
};
|
||||||
|
|
||||||
export let properties: EnvProperties = {
|
export let properties: EnvProperties = {
|
||||||
|
|
|
@ -25,7 +25,14 @@ let props: EnvProperties = {
|
||||||
searchLinkToServices: "/search/find/services",
|
searchLinkToServices: "/search/find/services",
|
||||||
searchLinkToAdvancedServices: "/search/advanced/services",
|
searchLinkToAdvancedServices: "/search/advanced/services",
|
||||||
reCaptchaSiteKey: null,
|
reCaptchaSiteKey: null,
|
||||||
footerGrantText : ""
|
footerGrantText : "",
|
||||||
|
|
||||||
|
naturalLanguageSearchAPI: "https://darelab.athenarc.gr/nl_search/api/fc4e_get_results/",
|
||||||
|
availableCommunitiesAPI: 'https://darelab.athenarc.gr/api/faircore/category-based-recommender/available-communities',
|
||||||
|
recommendationsForCommunityAPI: 'https://darelab.athenarc.gr/api/faircore/category-based-recommender/recommend',
|
||||||
|
recommendationsForOrcidAPI: 'https://darelab.athenarc.gr/api/faircore/user-to-item-recommender/recommend',
|
||||||
|
recommendationsForPublicationAPI: 'https://darelab.athenarc.gr/api/faircore/item-to-item-recommender/recommend/',
|
||||||
|
feedbackForRecommendationAPI: 'https://darelab.athenarc.gr/api/faircore/category-based-recommender/update/'
|
||||||
};
|
};
|
||||||
|
|
||||||
export let properties: EnvProperties = {
|
export let properties: EnvProperties = {
|
||||||
|
|
|
@ -25,7 +25,14 @@ let props: EnvProperties = {
|
||||||
searchLinkToServices: "/search/find/services",
|
searchLinkToServices: "/search/find/services",
|
||||||
searchLinkToAdvancedServices: "/search/advanced/services",
|
searchLinkToAdvancedServices: "/search/advanced/services",
|
||||||
reCaptchaSiteKey: null,
|
reCaptchaSiteKey: null,
|
||||||
footerGrantText : "This OpenAIRE gateway is part of a project that has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreements No. 777541 and 101017452"
|
footerGrantText : "This OpenAIRE gateway is part of a project that has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreements No. 777541 and 101017452",
|
||||||
|
|
||||||
|
naturalLanguageSearchAPI: "https://darelab.athenarc.gr/nl_search/api/fc4e_get_results/",
|
||||||
|
availableCommunitiesAPI: 'https://darelab.athenarc.gr/api/faircore/category-based-recommender/available-communities',
|
||||||
|
recommendationsForCommunityAPI: 'https://darelab.athenarc.gr/api/faircore/category-based-recommender/recommend',
|
||||||
|
recommendationsForOrcidAPI: 'https://darelab.athenarc.gr/api/faircore/user-to-item-recommender/recommend',
|
||||||
|
recommendationsForPublicationAPI: 'https://darelab.athenarc.gr/api/faircore/item-to-item-recommender/recommend/',
|
||||||
|
feedbackForRecommendationAPI: 'https://darelab.athenarc.gr/api/faircore/category-based-recommender/update/'
|
||||||
};
|
};
|
||||||
|
|
||||||
export let properties: EnvProperties = {
|
export let properties: EnvProperties = {
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
/***************************************************************************************************
|
|
||||||
* Load `$localize` onto the global scope - used if i18n tags appear in Angular templates.
|
|
||||||
*/
|
|
||||||
import '@angular/localize/init';
|
|
||||||
|
|
||||||
import { enableProdMode } from '@angular/core';
|
|
||||||
|
|
||||||
import {properties} from './environments/environment';
|
|
||||||
|
|
||||||
if (properties.environment !== "development") {
|
|
||||||
enableProdMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
export { AppServerModule } from './app/app.server.module';
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"extends": "./tsconfig.app.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"outDir": "../out-tsc/app-server",
|
|
||||||
"types": [
|
|
||||||
"node"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"main.server.ts",
|
|
||||||
"../server.ts"
|
|
||||||
],
|
|
||||||
"angularCompilerOptions": {
|
|
||||||
"entryModule": "./app/app.server.module#AppServerModule"
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue