Merge Angular 16 Irish Monitor to develop #33

Merged
k.triantafyllou merged 151 commits from angular-16-irish-monitor into develop 2024-02-13 09:32:41 +01:00
13 changed files with 70 additions and 423 deletions
Showing only changes of commit bbcfa595da - Show all commits

View File

@ -1,3 +1,4 @@
<div class="uk-flex uk-flex-center uk-flex-left@m">
<div *ngIf="showOptions && showOptions.linkToEntities.length > 0" class="uk-width-xlarge@l uk-width-large" [ngClass]="centerAlign ? 'uk-align-center':''">
<advanced-search-input (searchEmitter)="search(true)">
<div input type="select" [(value)]="showOptions.show" placeholder="Type" hint="Select..."
@ -10,6 +11,7 @@
<div search-input [(value)]="keyword" [placeholder]="'Search for ' + openaireEntities.RESULTS.toLowerCase() + '...'"
[searchInputClass]="'inner background'" (searchEmitter)="search(true)"></div>
</div>
</div>
<div *ngIf="!showSearchResults">
<div class="uk-text-center uk-text-large uk-text-meta uk-margin-large-top">
No {{showOptions?openaireEntities.RESULTS.toLowerCase() :'sources'}} yet...<br>Use the searchbar to find and link

View File

@ -63,7 +63,7 @@
<div class="uk-width-expand">
<div class="uk-margin-bottom">
<claim-entity [entity]="claim.target" [type]="claim.targetType" [properties]=properties
[externalPortalUrl]=externalPortalUrl [source]="true"></claim-entity>
[externalPortalUrl]=externalPortalUrl [source]="true" [linkAvailable]="isClaimAvailable(claim)"></claim-entity>
</div>
<div class="uk-margin-bottom">
<span *ngIf="isClaimAvailable(claim) else notAvailable" class="uk-label uk-label-success"

View File

@ -18,7 +18,7 @@ import {StringUtils} from "../../../utils/string-utils.class";
<div class="uk-flex">
<span *ngIf="!source" class="uk-text-meta uk-margin-small-right uk-text-large uk-text-nowrap">Link to:</span>
<publication-title [entity]="entity" param="id"
path="/search/result" [externalPortalUrl]=externalPortalUrl></publication-title>
path="/search/result" [externalPortalUrl]=externalPortalUrl [linkAvailable]="linkAvailable"></publication-title>
</div>
</div>
<div *ngIf="type == 'project'" [attr.uk-tooptip]="getEntityName(type)"
@ -40,6 +40,7 @@ export class ClaimEntityFormatter {
@Input() properties: EnvProperties;
@Input() externalPortalUrl: string = null;
@Input() source: boolean = true;
@Input() linkAvailable: boolean = true;
public openAIREEntities = OpenaireEntities;
constructor() {

View File

@ -10,8 +10,8 @@ import {RouterHelper} from '../../../utils/routerHelper.class';
<h6 class="uk-margin-remove multi-line-ellipsis lines-2">
<p class="uk-margin-remove">
<a *ngIf="!externalPortalUrl" [queryParams]="routerHelper.createQueryParam(param,entity.openaireId)"
[routerLink]="path" class="uk-link uk-link-heading">{{entity.title?entity.title:"[No title available]"}}</a>
<a *ngIf="externalPortalUrl" [href]="externalPortalUrl + path+'?'+param+'='+entity.openaireId" class="uk-link uk-link-heading custom-external">{{entity.title?entity.title:"[No title available]"}}</a>
[routerLink]="path" class="uk-link uk-link-heading" [class.uk-disabled]="!linkAvailable">{{entity.title?entity.title:"[No title available]"}}</a>
<a *ngIf="externalPortalUrl" [href]="externalPortalUrl + path+'?'+param+'='+entity.openaireId" class="uk-link uk-link-heading custom-external" [class.uk-disabled]="!linkAvailable">{{entity.title?entity.title:"[No title available]"}}</a>
</p>
</h6>
</ng-container>
@ -23,5 +23,6 @@ export class PublicationTitleFormatter {
@Input() path: string;
@Input() entity: any;
@Input() externalPortalUrl: string = null;
@Input() linkAvailable: boolean = true;
public routerHelper: RouterHelper = new RouterHelper();
}

View File

@ -73,11 +73,11 @@
<div id="tm-main" class="uk-section uk-padding-remove-top" *ngIf="showOptions.show != 'claim'">
<div>
<schema2jsonld *ngIf="url" [URL]="url" name="Link your {{openaireEntities.RESULTS}}" type="other"></schema2jsonld>
<div [class]="((showOptions.show == 'claim')?'':' uk-margin-top ')+' uk-container uk-container-large '">
<div class="uk-container uk-container-large">
<div *ngIf="properties" class="uk-section uk-padding-remove-top">
<div [class]="((showOptions.show == 'claim')?'':' uk-margin-top ')+' uk-container uk-container-large '">
<div class="uk-container uk-container-large">
<div class="uk-grid basketContainer" *ngIf="showOptions.show!='claim'" uk-grid>
<div class="uk-width-2-3 uk-position-z-index">
<div class="uk-width-2-3@m uk-position-z-index uk-flex-first@m uk-flex-last uk-margin-medium-top">
<h2 *ngIf="inlineEntity" class="uk-text-center">Link source to</h2>
<div *ngIf="showOptions.show=='source'">
<claim-result-search-form [selectedResults]="sources" [properties]=properties
@ -109,11 +109,11 @@
</div>
</div>
<!-- Basket-->
<div *ngIf="showOptions.show != 'claim'" class="uk-width-1-3">
<div *ngIf="showOptions.show != 'claim'" class="uk-width-1-3@m uk-flex-last@m uk-flex-first uk-margin-medium-top">
<div id="basket" uk-sticky="offset: 220; end: !*; media: @m" style="z-index: 0!important;">
<div class="uk-card uk-card-default linkingBasket">
<div class="uk-card-body uk-padding-small">
<div class="uk-margin-right">
<div>
<ng-container *ngIf="inlineEntity">
<div class="uk-margin-small-bottom">
<div class="uk-text-emphasis uk-text-bolder">Source</div>
@ -145,7 +145,7 @@
</li>
</ul>
<div *ngIf="showOptions.basketShowSources">
<div class="uk-height-medium uk-overflow-auto">
<div class="uk-height-max-medium uk-overflow-auto uk-padding uk-padding-remove-left uk-padding-remove-vertical">
<div *ngIf="showOptions.show == 'source'" class="uk-padding-small uk-padding-remove-horizontal" style="min-height:17px;">
<start-over *ngIf="showOptions.show == 'source' && sources.length> 0"
[results]="sources"
@ -173,7 +173,7 @@
</div>
</div>
<div *ngIf="showOptions.basketShowLinksTo">
<div class="uk-height-medium uk-overflow-auto">
<div class="uk-height-max-medium uk-overflow-auto uk-padding uk-padding-remove-left uk-padding-remove-vertical">
<ng-container *ngTemplateOutlet="destinations_basket"></ng-container>
</div>
</div>

View File

@ -1,225 +0,0 @@
import {
Component,
ElementRef,
EventEmitter,
HostListener,
Input,
OnDestroy,
OnInit,
Output,
ViewChild
} from "@angular/core";
import {Annotation, AnnotationService} from "./annotation.service";
import {ResultLandingInfo} from "../../utils/entities/resultLandingInfo";
import {EnvProperties} from "../../utils/properties/env-properties";
import {properties} from "../../../../environments/environment";
import {UserManagementService} from "../../services/user-management.service";
import {COOKIE, Session, User} from "../../login/utils/helper.class";
import {Subscriber} from "rxjs";
@Component({
selector: 'b2note',
template: `
<div *ngIf="annotations && annotations.length > 0" class="sideInfoTitle uk-margin-small-bottom">Annotations</div>
<div class="b2note">
<form #form ngNoForm *ngIf="pid && isLoggedIn"
[action]="properties.b2noteAPIURL + 'widget'"
method="post"
target="b2note_iframe"
class="uk-padding-small uk-padding-remove-vertical">
<!--URL of the annotated record-->
<input
type="hidden"
name="recordurl_tofeed"
[value]="url">
<!--PID of the annotated record-->
<input
type="hidden"
name="pid_tofeed"
[value]="pid">
</form>
<loading *ngIf="loading" class="uk-margin-medium-top"></loading>
<ul *ngIf="annotations && !loading" class="uk-list uk-list-divider">
<li *ngFor="let annotation of annotations.slice(0, visibleAnnotations); let i=index" uk-grid
class="uk-flex uk-flex-top uk-margin-remove-left">
<div [ngClass]="annotation.type" class="type">{{annotation.type}}</div>
<div [class.uk-width-1-3]="annotation.targets"
[class.uk-width-1-6@s]="annotation.targets">{{annotation.text}}</div>
<ul class="uk-width-expand uk-list uk-margin-remove-top" *ngIf="annotation.targets">
<li *ngFor="let target of annotation.targets.slice(0, annotation.targetSize)">
<a *ngIf="target.url" [href]="target.url" target="_blank">{{target.id}}</a>
<a *ngIf="!target.url" routerLink="/search/result"
[queryParams]="searchPid(target.id)">{{target.id}}</a>
</li>
<li *ngIf="annotation.targetSize < annotation.targets.length"><a
(click)="open(i)">+ {{annotation.targets.length - annotation.targetSize}}
more</a></li>
</ul>
</li>
</ul>
<div *ngIf="visibleAnnotations < annotations.length" class="uk-margin-medium-top uk-text-center">
<button class="uk-button uk-button-primary"
(click)="visibleAnnotations = (visibleAnnotations + annotationSize)">Load More
</button>
</div>
</div>
<div [class.uk-hidden]="!visible">
<div class="widget-container" cdkDrag>
<button type="button" class="close" aria-label="Close" (click)="toggleAnnotation($event)">
<span aria-hidden="true">×</span>
</button>
<iframe #iframe id="b2note_iframe" name="b2note_iframe" class="b2note-iframe">
</iframe>
</div>
</div>`,
styleUrls: ['annotation.css']
})
export class AnnotationComponent implements OnInit, OnDestroy {
@Input()
public landingInfo: ResultLandingInfo = null;
@Input()
public id: string = null;
public properties: EnvProperties = properties;
public url: string = null;
public pid: string = null;
public keywords: string[] = [];
public visible: boolean = false;
public annotations: Annotation[] = [];
public annotationSize: number = 10;
public isLoggedIn: boolean = Session.isLoggedIn();
public visibleAnnotations: number;
public loading: boolean = false;
public submitted: boolean = false;
@Output()
public pidEmitter: EventEmitter<string> = new EventEmitter<string>();
@ViewChild('iframe') iframe: ElementRef;
@ViewChild('form') form: ElementRef;
private subscriptions: any[] = [];
constructor(private annotationService: AnnotationService) {
}
@HostListener('window:message', ['$event'])
public onChange(event) {
if (this.properties.b2noteAPIURL.includes(event.origin)) {
if (event.data === "B2NOTE loaded") {
let token = COOKIE.getCookie('AccessToken');
this.iframe.nativeElement.contentWindow.postMessage({token: token}, this.properties.b2noteAPIURL);
} else {
this.getAnnotations();
}
}
}
ngOnInit(): void {
this.visibleAnnotations = this.annotationSize;
if (typeof window !== "undefined") {
let id = this.id;
this.url = window.location.href;
if (this.landingInfo.deletedByInferenceIds) {
id = this.landingInfo.deletedByInferenceIds[0];
this.url = this.url.replace(this.id, id);
}
if (this.landingInfo.identifiers && this.landingInfo.identifiers.size > 0) {
if (this.landingInfo.identifiers.get('doi')) {
this.pid = this.landingInfo.identifiers.get('doi')[0];
} else {
const key: string = this.landingInfo.identifiers.keys().next().value;
if (key) {
this.pid = this.landingInfo.identifiers.get(key)[0];
}
}
}
if (this.pid) {
this.getAnnotations();
}
this.pidEmitter.emit(this.pid);
}
}
public get enabled(): boolean {
return this.pid && this.isLoggedIn;
}
private clearSubscriptions() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
}
});
this.subscriptions = [];
}
private getAnnotations() {
if (!this.annotations || this.annotations.length === 0) {
this.loading = true;
}
this.subscriptions.push(this.annotationService.getAllAnnotations(this.pid).subscribe(annotations => {
this.annotations.forEach((annotation, index) => {
if (!annotations.find(element => element.type === annotation.type && element.text === annotation.text)) {
this.annotations.splice(index, 1);
}
});
annotations.forEach(annotation => {
if (!this.annotations.find(element => element.type === annotation.type && element.text === annotation.text)) {
annotation.targetSize = 3;
this.annotationService.getAnnotationTargets(annotation.text, annotation.type).subscribe(targets => {
annotation.targets = targets.filter(target => target.id !== this.pid);
});
this.annotations.push(annotation);
}
});
this.annotations = this.sort(this.annotations);
this.loading = false;
}, error => {
this.loading = false;
}));
}
public sort(annotations: Annotation[]): Annotation[] {
return annotations.sort((a, b) => {
if (a.type === b.type) {
return 1;
} else if (a.type === 'semantic') {
return -1;
} else if (b.type === 'semantic') {
return 1;
} else if (a.type === 'keyword') {
return -1;
} else if (b.type === 'keyword') {
return 1;
}
});
}
public searchPid(pid: string): { [k: string]: any; } {
return {
pid: pid
}
}
ngOnDestroy() {
this.clearSubscriptions();
}
toggleAnnotation(event) {
if (this.visible) {
event.preventDefault();
} else if(!this.submitted) {
this.form.nativeElement.submit();
this.submitted = true;
}
this.visible = !this.visible;
}
open(i: number) {
this.annotations.forEach((annotation, index) => {
if (index != i) {
annotation.targetSize = 3;
} else {
annotation.targetSize = annotation.targets.length
}
});
}
}

View File

@ -1,41 +0,0 @@
.widget-container {
position: fixed;
left: 50%;
top: 50%;
z-index: 1000;
padding: 19px;
margin-left: -167px;
margin-top: -311px;
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
0 2px 2px 0 rgba(0, 0, 0, 0.14),
0 1px 5px 0 rgba(0, 0, 0, 0.12);
border: 1px solid #e3e3e3;
border-radius: 4px;
outline: 0;
min-height: 20px;
background-color: #f5f5f5;
cursor: move;
}
.widget-container:hover, .widget-container:active{
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12);
}
.close {
float: right;
padding: 0;
cursor: pointer;
background: transparent;
border: 0;
font-size: 21px;
font-weight: bold;
opacity: 0.2;
}
.b2note-iframe {
width: 100%;
height: 600px;
border: 1px solid #dddddd;
}

View File

@ -1,13 +0,0 @@
import {NgModule} from "@angular/core";
import {AnnotationComponent} from "./annotation.component";
import {CommonModule} from "@angular/common";
import {DragDropModule} from "@angular/cdk/drag-drop";
import {RouterModule} from "@angular/router";
import {LoadingModule} from "../../utils/loading/loading.module";
@NgModule({
imports: [CommonModule, DragDropModule, RouterModule, LoadingModule],
declarations: [AnnotationComponent],
exports: [AnnotationComponent]
})
export class AnnotationModule {}

View File

@ -1,95 +0,0 @@
import {Injectable} from "@angular/core";
import {HttpClient} from "@angular/common/http";
import {Observable} from "rxjs";
import {EnvProperties} from "../../utils/properties/env-properties";
import {map} from "rxjs/operators";
import {properties} from "../../../../environments/environment";
export interface AnnotationTarget {
id: string;
url: string;
}
export interface Annotation {
text: string;
type: 'semantic' | 'keyword' | 'comment';
targets?: AnnotationTarget[];
targetSize?: number;
}
@Injectable({
providedIn: "root"
})
export class AnnotationService {
api = 'api/';
constructor(private http: HttpClient) {
}
getAllAnnotations(source: string): Observable<Annotation[]> {
let url = properties.b2noteAPIURL + this.api + 'annotations?target-id[]=' + encodeURIComponent(source);
return this.http.get<Annotation[]>(url).pipe(map((response: any[]) => {
return this.parseAnnotations(response);
}));
}
getAnnotationTargets(value: string, type: 'semantic' | 'keyword' | 'comment'): Observable<AnnotationTarget[]> {
let url = properties.b2noteAPIURL + this.api + 'annotations?value=' + encodeURIComponent(value) + '&type[]=' + type;
return this.http.get<AnnotationTarget[]>(url).pipe(map((response: any[]) => {
return this.parseAnnotationTargets(response);
}));
}
private parseAnnotations(response: any[]): Annotation[] {
let annotations: Annotation[] = [];
if (response && response.length > 0) {
response.forEach(value => {
if (value.visibility === 'public') {
let body = value.body;
if (body.type === 'TextualBody') {
if (body.purpose === 'tagging') {
annotations.push({
text: body.value,
type: "keyword"
});
} else {
annotations.push({
text: body.value,
type: "comment"
});
}
} else {
let items = body.items;
let text: string = null;
items.forEach(item => {
if (item.type === 'TextualBody') {
text = item.value;
}
});
annotations.push({
text: text,
type: "semantic"
});
}
}
});
}
return annotations;
}
private parseAnnotationTargets(response: any[]): AnnotationTarget[] {
let targets: AnnotationTarget[] = [];
if (response && response.length > 0) {
response.forEach(value => {
if (value.visibility === 'public') {
targets.push({
id: value.target.id,
url: value.target.source
});
}
});
}
return targets;
}
}

View File

@ -134,7 +134,6 @@ export class ResultLandingComponent {
public isLoggedIn: boolean = false;
public pid: string;
// @ViewChild("annotation") annotation: AnnotationComponent;
public contextsWithLink: any;
public relatedClassFilters: Option[]=[{"label": "All relations", "value": ""}];

View File

@ -20,7 +20,6 @@ import {ShowAuthorsModule} from "../../utils/authors/showAuthors.module";
import {HelperModule} from "../../utils/helper/helper.module";
import {ResultLandingUtilsModule} from "../landing-utils/resultLandingUtils.module";
import {AlertModalModule} from "../../utils/modal/alertModal.module";
import {AnnotationModule} from "../annotation/annotation.module";
import {LandingHeaderModule} from "../landing-utils/landing-header/landing-header.module";
import {NoLoadPaging} from "../../searchPages/searchUtils/no-load-paging.module";
import {ResultPreviewModule} from "../../utils/result-preview/result-preview.module";
@ -45,7 +44,7 @@ import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.mod
CiteThisModule, PagingModule, IFrameModule,
AltMetricsModule, Schema2jsonldModule, SEOServiceModule,
DeletedByInferenceModule, ShowAuthorsModule, HelperModule, ResultLandingUtilsModule, AlertModalModule,
AnnotationModule, LandingHeaderModule, NoLoadPaging, ResultPreviewModule, FeedbackModule, TabsModule, LoadingModule,
LandingHeaderModule, NoLoadPaging, ResultPreviewModule, FeedbackModule, TabsModule, LoadingModule,
OrcidModule, IconsModule, InputModule, EGIDataTransferModule, RecaptchaModule,
SdgFosSuggestModule, FullScreenModalModule, SafeHtmlPipeModule, EntityActionsModule
],

View File

@ -85,17 +85,15 @@ export let common: EnvProperties = {
shareInZenodoPage: '/participate/deposit/zenodo',
afterLoginRedirectLink: '/myCommunities',
searchLinkToCommunities: '/search/find/communities',
openOrgsUrl:"https://beta.orgs.openaire.eu"
openOrgsUrl:"https://beta.orgs.openaire.eu",
}
export let commonDev: EnvProperties = {
environment: "development",
pdfStatisticsAPIURL: "https://beta.services.openaire.eu/pdf-stats",
statisticsAPIURL: "http://vatopedi.di.uoa.gr:8080/stats/",
statisticsAPIURL: "https://beta.services.openaire.eu/stats-api/",
statisticsFrameAPIURL: "https://beta.openaire.eu/stats/",
statisticsFrameNewAPIURL: "https://stats.madgik.di.uoa.gr/stats-api/",
statisticsFrameNewAPIURL: "https://beta.services.openaire.eu/stats-tool/",
claimsAPIURL: "http://scoobydoo.di.uoa.gr:8880/dnet-claims-service-2.0.0-SNAPSHOT/rest/claimsService/",
searchAPIURLLAst: "http://beta.services.openaire.eu/search/v2/api/",
searchResourcesAPIURL: "https://beta.services.openaire.eu/search/v2/api/resources",
@ -203,7 +201,7 @@ export let commonBeta: EnvProperties = {
export let commonProd: EnvProperties = {
environment: "production",
pdfStatisticsAPIURL: "https://services.openaire.eu/pdf-stats",
statisticsAPIURL: "https://beta.services.openaire.eu/stats-api/",
statisticsAPIURL: "https://services.openaire.eu/stats-api/",
statisticsFrameAPIURL: "https://www.openaire.eu/stats/",
statisticsFrameNewAPIURL: "https://services.openaire.eu/stats-tool/",
claimsAPIURL: "https://services.openaire.eu/claims-new/rest/claimsService/",

View File

@ -143,28 +143,49 @@ export class ISVocabulariesService {
parseFOS(data: any): AutoCompleteValue[] {
let array: AutoCompleteValue[] = []
for (let fos of data) {
let children = data.reverse();
while(children && children.length > 0) {
let fos = children.pop();
let value: AutoCompleteValue = new AutoCompleteValue();
value.id = fos.id;//data[i].code;
value.label = fos.label;
array.push(value);
if(fos.children) {
for (let fos2 of fos.children) {
let value: AutoCompleteValue = new AutoCompleteValue();
value.id = fos2.id;//data[i].code;
value.label = fos2.label;
array.push(value);
if(fos2.children) {
for (let fos3 of fos2.children) {
let value: AutoCompleteValue = new AutoCompleteValue();
value.id = fos3.id;//data[i].code;
value.label = fos3.label;
array.push(value);
}
}
if(fos.children && fos.children.length > 0) {
for (let i=fos.children.length-1; i>=0; i--) {
children.push(fos.children[i]);
}
}
}
// for (let fos of data) {
// let value: AutoCompleteValue = new AutoCompleteValue();
// value.id = fos.id;//data[i].code;
// value.label = fos.label;
// array.push(value);
// if(fos.children) {
// for (let fos2 of fos.children) {
// let value: AutoCompleteValue = new AutoCompleteValue();
// value.id = fos2.id;//data[i].code;
// value.label = fos2.label;
// array.push(value);
// if(fos2.children) {
// for (let fos3 of fos2.children) {
// let value: AutoCompleteValue = new AutoCompleteValue();
// value.id = fos3.id;//data[i].code;
// value.label = fos3.label;
// array.push(value);
// // if(fos3.children) {
// // for (let fos4 of fos3.children) {
// // let value: AutoCompleteValue = new AutoCompleteValue();
// // value.id = fos4.id;//data[i].code;
// // value.label = fos4.label;
// // array.push(value);
// // }
// // }
// }
// }
// }
// }
// }
return array;
}