1 |
61381
|
k.triantaf
|
import {
|
2 |
|
|
Component,
|
3 |
|
|
ElementRef,
|
4 |
|
|
EventEmitter,
|
5 |
|
|
HostListener,
|
6 |
|
|
Input,
|
7 |
|
|
OnDestroy,
|
8 |
|
|
OnInit,
|
9 |
|
|
Output,
|
10 |
|
|
ViewChild
|
11 |
|
|
} from "@angular/core";
|
12 |
|
|
import {Annotation, AnnotationService} from "./annotation.service";
|
13 |
|
|
import {ResultLandingInfo} from "../../utils/entities/resultLandingInfo";
|
14 |
|
|
import {EnvProperties} from "../../utils/properties/env-properties";
|
15 |
|
|
import {properties} from "../../../../environments/environment";
|
16 |
|
|
import {UserManagementService} from "../../services/user-management.service";
|
17 |
|
|
import {COOKIE, Session, User} from "../../login/utils/helper.class";
|
18 |
|
|
import {Subscriber} from "rxjs";
|
19 |
|
|
|
20 |
|
|
@Component({
|
21 |
|
|
selector: 'b2note',
|
22 |
|
|
template: `
|
23 |
|
|
<div *ngIf="annotations && annotations.length > 0" class="sideInfoTitle uk-margin-small-bottom">Annotations</div>
|
24 |
|
|
<div class="b2note">
|
25 |
|
|
<form #form ngNoForm *ngIf="pid && isLoggedIn"
|
26 |
|
|
[action]="properties.b2noteAPIURL + 'widget'"
|
27 |
|
|
method="post"
|
28 |
|
|
target="b2note_iframe"
|
29 |
|
|
class="uk-padding-small uk-padding-remove-vertical">
|
30 |
|
|
<!--URL of the annotated record-->
|
31 |
|
|
<input
|
32 |
|
|
type="hidden"
|
33 |
|
|
name="recordurl_tofeed"
|
34 |
|
|
[value]="url">
|
35 |
|
|
<!--PID of the annotated record-->
|
36 |
|
|
<input
|
37 |
|
|
type="hidden"
|
38 |
|
|
name="pid_tofeed"
|
39 |
|
|
[value]="pid">
|
40 |
|
|
</form>
|
41 |
|
|
<loading *ngIf="loading" class="uk-margin-medium-top"></loading>
|
42 |
|
|
<ul *ngIf="annotations && !loading" class="uk-list uk-list-divider">
|
43 |
|
|
<li *ngFor="let annotation of annotations.slice(0, visibleAnnotations); let i=index" uk-grid
|
44 |
|
|
class="uk-flex uk-flex-top uk-margin-remove-left">
|
45 |
|
|
<div [ngClass]="annotation.type" class="type">{{annotation.type}}</div>
|
46 |
|
|
<div [class.uk-width-1-3]="annotation.targets"
|
47 |
|
|
[class.uk-width-1-6@s]="annotation.targets">{{annotation.text}}</div>
|
48 |
|
|
<ul class="uk-width-expand uk-list uk-margin-remove-top" *ngIf="annotation.targets">
|
49 |
|
|
<li *ngFor="let target of annotation.targets.slice(0, annotation.targetSize)">
|
50 |
|
|
<a *ngIf="target.url" [href]="target.url" target="_blank">{{target.id}}</a>
|
51 |
|
|
<a *ngIf="!target.url" routerLink="/search/result"
|
52 |
|
|
[queryParams]="searchPid(target.id)">{{target.id}}</a>
|
53 |
|
|
</li>
|
54 |
|
|
<li *ngIf="annotation.targetSize < annotation.targets.length"><a
|
55 |
|
|
(click)="open(i)">+ {{annotation.targets.length - annotation.targetSize}}
|
56 |
|
|
more</a></li>
|
57 |
|
|
</ul>
|
58 |
|
|
</li>
|
59 |
|
|
</ul>
|
60 |
|
|
<div *ngIf="visibleAnnotations < annotations.length" class="uk-margin-medium-top uk-text-center">
|
61 |
|
|
<button class="uk-button uk-button-primary"
|
62 |
|
|
(click)="visibleAnnotations = (visibleAnnotations + annotationSize)">Load More
|
63 |
|
|
</button>
|
64 |
|
|
</div>
|
65 |
|
|
</div>
|
66 |
|
|
<div [class.uk-hidden]="!visible">
|
67 |
|
|
<div class="widget-container" cdkDrag>
|
68 |
|
|
<button type="button" class="close" aria-label="Close" (click)="toggleAnnotation($event)">
|
69 |
|
|
<span aria-hidden="true">×</span>
|
70 |
|
|
</button>
|
71 |
|
|
<iframe #iframe id="b2note_iframe" name="b2note_iframe" class="b2note-iframe">
|
72 |
|
|
</iframe>
|
73 |
|
|
</div>
|
74 |
|
|
</div>`,
|
75 |
|
|
styleUrls: ['annotation.css']
|
76 |
|
|
})
|
77 |
|
|
export class AnnotationComponent implements OnInit, OnDestroy {
|
78 |
|
|
|
79 |
|
|
@Input()
|
80 |
|
|
public landingInfo: ResultLandingInfo = null;
|
81 |
|
|
@Input()
|
82 |
|
|
public id: string = null;
|
83 |
|
|
public properties: EnvProperties = properties;
|
84 |
|
|
public url: string = null;
|
85 |
|
|
public pid: string = null;
|
86 |
|
|
public keywords: string[] = [];
|
87 |
|
|
public visible: boolean = false;
|
88 |
|
|
public annotations: Annotation[] = [];
|
89 |
|
|
public annotationSize: number = 10;
|
90 |
|
|
public isLoggedIn: boolean = Session.isLoggedIn();
|
91 |
|
|
public visibleAnnotations: number;
|
92 |
|
|
public loading: boolean = false;
|
93 |
|
|
public submitted: boolean = false;
|
94 |
|
|
@Output()
|
95 |
|
|
public pidEmitter: EventEmitter<string> = new EventEmitter<string>();
|
96 |
|
|
@ViewChild('iframe') iframe: ElementRef;
|
97 |
|
|
@ViewChild('form') form: ElementRef;
|
98 |
|
|
private subscriptions: any[] = [];
|
99 |
|
|
|
100 |
|
|
constructor(private annotationService: AnnotationService) {
|
101 |
|
|
}
|
102 |
|
|
|
103 |
|
|
@HostListener('window:message', ['$event'])
|
104 |
|
|
public onChange(event) {
|
105 |
|
|
if (this.properties.b2noteAPIURL.includes(event.origin)) {
|
106 |
|
|
if (event.data === "B2NOTE loaded") {
|
107 |
|
|
let token = COOKIE.getCookie('AccessToken');
|
108 |
|
|
this.iframe.nativeElement.contentWindow.postMessage({token: token}, this.properties.b2noteAPIURL);
|
109 |
|
|
} else {
|
110 |
|
|
this.getAnnotations();
|
111 |
|
|
}
|
112 |
|
|
}
|
113 |
|
|
}
|
114 |
|
|
|
115 |
|
|
ngOnInit(): void {
|
116 |
|
|
this.visibleAnnotations = this.annotationSize;
|
117 |
|
|
if (typeof window !== "undefined") {
|
118 |
|
|
let id = this.id;
|
119 |
|
|
this.url = window.location.href;
|
120 |
|
|
if (this.landingInfo.deletedByInferenceIds) {
|
121 |
|
|
id = this.landingInfo.deletedByInferenceIds[0];
|
122 |
|
|
this.url = this.url.replace(this.id, id);
|
123 |
|
|
}
|
124 |
|
|
if (this.landingInfo.identifiers && this.landingInfo.identifiers.size > 0) {
|
125 |
|
|
if (this.landingInfo.identifiers.get('doi')) {
|
126 |
|
|
this.pid = this.landingInfo.identifiers.get('doi')[0];
|
127 |
|
|
} else {
|
128 |
|
|
const key: string = this.landingInfo.identifiers.keys().next().value;
|
129 |
|
|
if (key) {
|
130 |
|
|
this.pid = this.landingInfo.identifiers.get(key)[0];
|
131 |
|
|
}
|
132 |
|
|
}
|
133 |
|
|
}
|
134 |
|
|
if (this.pid) {
|
135 |
|
|
this.getAnnotations();
|
136 |
|
|
}
|
137 |
|
|
this.pidEmitter.emit(this.pid);
|
138 |
|
|
}
|
139 |
|
|
}
|
140 |
|
|
|
141 |
|
|
public get enabled(): boolean {
|
142 |
|
|
return this.pid && this.isLoggedIn;
|
143 |
|
|
}
|
144 |
|
|
|
145 |
|
|
private clearSubscriptions() {
|
146 |
|
|
this.subscriptions.forEach(subscription => {
|
147 |
|
|
if (subscription instanceof Subscriber) {
|
148 |
|
|
subscription.unsubscribe();
|
149 |
|
|
}
|
150 |
|
|
});
|
151 |
|
|
this.subscriptions = [];
|
152 |
|
|
}
|
153 |
|
|
|
154 |
|
|
private getAnnotations() {
|
155 |
|
|
if (!this.annotations || this.annotations.length === 0) {
|
156 |
|
|
this.loading = true;
|
157 |
|
|
}
|
158 |
|
|
this.subscriptions.push(this.annotationService.getAllAnnotations(this.pid).subscribe(annotations => {
|
159 |
|
|
this.annotations.forEach((annotation, index) => {
|
160 |
|
|
if (!annotations.find(element => element.type === annotation.type && element.text === annotation.text)) {
|
161 |
|
|
this.annotations.splice(index, 1);
|
162 |
|
|
}
|
163 |
|
|
});
|
164 |
|
|
annotations.forEach(annotation => {
|
165 |
|
|
if (!this.annotations.find(element => element.type === annotation.type && element.text === annotation.text)) {
|
166 |
|
|
annotation.targetSize = 3;
|
167 |
|
|
this.annotationService.getAnnotationTargets(annotation.text, annotation.type).subscribe(targets => {
|
168 |
|
|
annotation.targets = targets.filter(target => target.id !== this.pid);
|
169 |
|
|
});
|
170 |
|
|
this.annotations.push(annotation);
|
171 |
|
|
}
|
172 |
|
|
});
|
173 |
|
|
this.annotations = this.sort(this.annotations);
|
174 |
|
|
this.loading = false;
|
175 |
|
|
}, error => {
|
176 |
|
|
this.loading = false;
|
177 |
|
|
}));
|
178 |
|
|
}
|
179 |
|
|
|
180 |
|
|
public sort(annotations: Annotation[]): Annotation[] {
|
181 |
|
|
return annotations.sort((a, b) => {
|
182 |
|
|
if (a.type === b.type) {
|
183 |
|
|
return 1;
|
184 |
|
|
} else if (a.type === 'semantic') {
|
185 |
|
|
return -1;
|
186 |
|
|
} else if (b.type === 'semantic') {
|
187 |
|
|
return 1;
|
188 |
|
|
} else if (a.type === 'keyword') {
|
189 |
|
|
return -1;
|
190 |
|
|
} else if (b.type === 'keyword') {
|
191 |
|
|
return 1;
|
192 |
|
|
}
|
193 |
|
|
});
|
194 |
|
|
}
|
195 |
|
|
|
196 |
|
|
public searchPid(pid: string): { [k: string]: any; } {
|
197 |
|
|
return {
|
198 |
|
|
pid: pid
|
199 |
|
|
}
|
200 |
|
|
}
|
201 |
|
|
|
202 |
|
|
ngOnDestroy() {
|
203 |
|
|
this.clearSubscriptions();
|
204 |
|
|
}
|
205 |
|
|
|
206 |
|
|
toggleAnnotation(event) {
|
207 |
|
|
if (this.visible) {
|
208 |
|
|
event.preventDefault();
|
209 |
|
|
} else if(!this.submitted) {
|
210 |
|
|
this.form.nativeElement.submit();
|
211 |
|
|
this.submitted = true;
|
212 |
|
|
}
|
213 |
|
|
this.visible = !this.visible;
|
214 |
|
|
}
|
215 |
|
|
|
216 |
|
|
open(i: number) {
|
217 |
|
|
this.annotations.forEach((annotation, index) => {
|
218 |
|
|
if (index != i) {
|
219 |
|
|
annotation.targetSize = 3;
|
220 |
|
|
} else {
|
221 |
|
|
annotation.targetSize = annotation.targets.length
|
222 |
|
|
}
|
223 |
|
|
});
|
224 |
|
|
}
|
225 |
|
|
}
|