openaire-library/landingPages/annotation/annotation.component.ts

226 lines
7.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
});
}
}