[Library | Trunk]: Finish annotations. Add new registry url property. Add new registry service

git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-services-library/trunk/ng-openaire-library/src/app@59228 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
k.triantafyllou 2020-08-06 11:50:08 +00:00
parent e3ea7dc45a
commit ae76e56dab
7 changed files with 152 additions and 48 deletions

View File

@ -1,15 +1,18 @@
import {Component, HostListener, Input, OnDestroy, OnInit} from "@angular/core"; import {Component, ElementRef, HostListener, Input, OnDestroy, OnInit, ViewChild} from "@angular/core";
import {Annotation, AnnotationService} from "./annotation.service"; import {Annotation, AnnotationService} from "./annotation.service";
import {ResultLandingInfo} from "../../utils/entities/resultLandingInfo"; import {ResultLandingInfo} from "../../utils/entities/resultLandingInfo";
import {EnvProperties} from "../../utils/properties/env-properties"; import {EnvProperties} from "../../utils/properties/env-properties";
import {properties} from "../../../../environments/environment"; import {properties} from "../../../../environments/environment";
import {UserManagementService} from "../../services/user-management.service";
import {COOKIE} from "../../login/utils/helper.class";
import {Subscriber} from "rxjs";
@Component({ @Component({
selector: 'b2note', selector: 'b2note',
template: ` template: `
<div class="sideInfoTitle uk-margin-small-bottom">Annotations</div> <div class="sideInfoTitle uk-margin-small-bottom">Annotations</div>
<div class="b2note"> <div class="b2note">
<form ngNoForm *ngIf="pid" <form ngNoForm *ngIf="pid && user"
[action]="properties.b2noteAPIURL + 'widget'" [action]="properties.b2noteAPIURL + 'widget'"
method="post" method="post"
target="b2note_iframe" target="b2note_iframe"
@ -38,8 +41,10 @@ import {properties} from "../../../../environments/environment";
<span>add annotation</span> <span>add annotation</span>
</button> </button>
</form> </form>
<div *ngIf="!pid"> <div *ngIf="!pid || !user">
<button class="uk-flex uk-flex-middle disabled" title="Annotations are only available for resources with a PID (persistent identifier) like DOI, handle, PMID"> <button class="uk-flex uk-flex-middle disabled"
[title]="!pid?'Annotations are only available for resources with a PID (persistent identifier) like DOI, handle, PMID':
'Annotations are only available for logged in users'">
<img src="assets/common-assets/b2note.png" width="48" height="24"> <img src="assets/common-assets/b2note.png" width="48" height="24">
<span>add annotation</span> <span>add annotation</span>
</button> </button>
@ -65,7 +70,7 @@ import {properties} from "../../../../environments/environment";
<span aria-hidden="true">×</span> <span aria-hidden="true">×</span>
</button> </button>
<!--The glorious iframe with the running app!--> <!--The glorious iframe with the running app!-->
<iframe id="b2note_iframe" name="b2note_iframe" class="b2note-iframe"> <iframe #iframe id="b2note_iframe" name="b2note_iframe" class="b2note-iframe">
</iframe> </iframe>
</div> </div>
</div>`, </div>`,
@ -84,19 +89,33 @@ export class AnnotationComponent implements OnInit, OnDestroy {
public visible: boolean = false; public visible: boolean = false;
public annotations: Annotation[] = []; public annotations: Annotation[] = [];
public annotationSize: number = 3; public annotationSize: number = 3;
public user;
public visibleAnnotations: number; public visibleAnnotations: number;
@ViewChild('iframe') iframe: ElementRef;
private subscriptions: any[] = [];
constructor(private annotationService: AnnotationService) { constructor(private annotationService: AnnotationService,
private userManagementService: UserManagementService) {
} }
@HostListener('window:message', ['$event']) @HostListener('window:message', ['$event'])
public onChange(event) { public onChange(event) {
if(this.properties.b2noteAPIURL.includes(event.origin)) { if(this.properties.b2noteAPIURL.includes(event.origin)) {
this.getAnnotations(); if(event.data === "B2NOTE loaded") {
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
let token = COOKIE.getCookie('AccessToken');
this.iframe.nativeElement.contentWindow.postMessage({token: token}, this.properties.b2noteAPIURL);
}));
} else {
this.getAnnotations();
}
} }
} }
ngOnInit(): void { ngOnInit(): void {
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
this.user = user;
}));
this.visibleAnnotations = this.annotationSize; this.visibleAnnotations = this.annotationSize;
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
let id = this.id; let id = this.id;
@ -121,6 +140,15 @@ export class AnnotationComponent implements OnInit, OnDestroy {
} }
} }
private clearSubscriptions() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
}
});
this.subscriptions = [];
}
private getAnnotations() { private getAnnotations() {
this.annotationService.getAllAnnotations(this.properties, this.pid).subscribe(annotations => { this.annotationService.getAllAnnotations(this.properties, this.pid).subscribe(annotations => {
this.annotations = annotations; this.annotations = annotations;
@ -131,6 +159,7 @@ export class AnnotationComponent implements OnInit, OnDestroy {
} }
ngOnDestroy(): void { ngOnDestroy(): void {
this.clearSubscriptions();
} }
public toggleAnnotation(event) { public toggleAnnotation(event) {

View File

@ -8,4 +8,4 @@ import {DragDropModule} from "@angular/cdk/drag-drop";
declarations: [AnnotationComponent], declarations: [AnnotationComponent],
exports: [AnnotationComponent] exports: [AnnotationComponent]
}) })
export class AnnotationModule {} export class AnnotationModule {}

View File

@ -52,32 +52,46 @@ export class Session{
//Methods to check roles //Methods to check roles
public static isClaimsCurator(user: User): boolean { public static isClaimsCurator(user: User): boolean {
return user && return user &&
user.role.indexOf('urn:geant:openaire.eu:group:Curator+-+Claim#aai.openaire.eu') !== -1; (user.role.indexOf('urn:geant:openaire.eu:group:Curator+-+Claim#aai.openaire.eu') !== -1 ||
user.role.indexOf('CURATOR_CLAIM') !== -1);
} }
public static isCommunityCurator(user: User): boolean { public static isCommunityCurator(user: User): boolean {
return user && return user &&
user.role.indexOf('urn:geant:openaire.eu:group:Curator+-+Community#aai.openaire.eu') !== -1; (user.role.indexOf('urn:geant:openaire.eu:group:Curator+-+Community#aai.openaire.eu') !== -1||
user.role.indexOf('CURATOR_COMMUNITY') !== -1);
} }
public static isMonitorCurator(user: User): boolean { public static isMonitorCurator(user: User): boolean {
return user && return user &&
(user.role.indexOf('urn:geant:openaire.eu:group:Expert+-+Funder#aai.openaire.eu') !== -1 || user.role.indexOf('urn:geant:openaire.eu:group:Curator+-+Funder#aai.openaire.eu') !== -1); (user.role.indexOf('urn:geant:openaire.eu:group:Expert+-+Funder#aai.openaire.eu') !== -1 ||
user.role.indexOf('urn:geant:openaire.eu:group:Curator+-+Funder#aai.openaire.eu') !== -1);
} }
public static isPortalAdministrator(user: User): boolean { public static isPortalAdministrator(user: User): boolean {
return user && return user &&
user.role.indexOf('urn:geant:openaire.eu:group:Portal+Administrator#aai.openaire.eu') !== -1; (user.role.indexOf('urn:geant:openaire.eu:group:Portal+Administrator#aai.openaire.eu') !== -1 ||
user.role.indexOf('PORTAL_ADMINISTRATOR') !== -1);
} }
public static isUserManager(user: User): boolean { public static isUserManager(user: User): boolean {
return user && return user &&
user.role.indexOf('urn:geant:openaire.eu:group:User+Manager#aai.openaire.eu') !== -1; (user.role.indexOf('urn:geant:openaire.eu:group:User+Manager#aai.openaire.eu') !== -1 ||
user.role.indexOf('USER_MANAGER') !== -1);
}
public static isSubscriber(type: string, id: string, user: User): boolean {
return user && user.role.indexOf(type.toUpperCase() + '_' + id.toUpperCase()) !== -1
}
public static isManager(type: string, id: string, user: User): boolean {
return user && user.role.indexOf(type.toUpperCase() + '_' + id.toUpperCase() + '_MANAGER') !== -1
} }
public static isRegisteredUser(user: User): boolean { public static isRegisteredUser(user: User): boolean {
return user && return user &&
user.role.indexOf('urn:geant:openaire.eu:group:Registered+User#aai.openaire.eu') !== -1; (user.role.indexOf('urn:geant:openaire.eu:group:Registered+User#aai.openaire.eu') !== -1 ||
user.role.indexOf('REGISTERED_USER') !== -1);
} }

View File

@ -3,39 +3,30 @@ import {HttpHeaders} from "@angular/common/http";
export class CustomOptions { export class CustomOptions {
/* public static registryOptions(): any {
public static getAuthOptionsWithBody(): RequestOptions { return {
const headers = new Headers(); headers: new HttpHeaders({
headers.append('Content-Type', 'application/json'); 'Content-Type': 'application/json',
headers.append('X-XSRF-TOKEN', COOKIE.getCookie(COOKIE.cookieName_id)); }), withCredentials: true
const options = new RequestOptions({ headers: headers, withCredentials: true }); };
return options; }
}
*/
public static getAuthOptionsWithBody():{} { public static getAuthOptionsWithBody():{} {
return { return {
headers: new HttpHeaders({ headers: new HttpHeaders({
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-XSRF-TOKEN': COOKIE.getCookie(COOKIE.cookieName_id)?COOKIE.getCookie(COOKIE.cookieName_id):'' 'X-XSRF-TOKEN': COOKIE.getCookie(COOKIE.cookieName_id)?COOKIE.getCookie(COOKIE.cookieName_id):'',
'Access-Control-Allow-Origin': '*'
}), withCredentials: true }), withCredentials: true
}; };
} }
/*
public static getAuthOptions(): RequestOptions {
const headers = new Headers();
headers.append('X-XSRF-TOKEN', COOKIE.getCookie(COOKIE.cookieName_id));
const options = new RequestOptions({ headers: headers, withCredentials: true });
return options;
}
*/
public static getAuthOptions():any { public static getAuthOptions():any {
const httpOptions = { const httpOptions = {
headers: new HttpHeaders({ headers: new HttpHeaders({
'X-XSRF-TOKEN': (COOKIE.getCookie(COOKIE.cookieName_id))?COOKIE.getCookie(COOKIE.cookieName_id):'', 'X-XSRF-TOKEN': (COOKIE.getCookie(COOKIE.cookieName_id))?COOKIE.getCookie(COOKIE.cookieName_id):'',
'Access-Control-Allow-Origin': '*'
}), withCredentials: true }), withCredentials: true
}; };
return httpOptions; return httpOptions;

View File

@ -4,8 +4,8 @@ import {BehaviorSubject, from, Observable, of} from "rxjs";
import {COOKIE, User} from "../login/utils/helper.class"; import {COOKIE, User} from "../login/utils/helper.class";
import {catchError, map, timeout} from "rxjs/operators"; import {catchError, map, timeout} from "rxjs/operators";
import {NavigationEnd, Router} from "@angular/router"; import {NavigationEnd, Router} from "@angular/router";
import {EnvironmentSpecificService} from "../utils/properties/environment-specific.service";
import {properties} from "../../../environments/environment"; import {properties} from "../../../environments/environment";
import {CustomOptions} from "./servicesUtils/customOptions.class";
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -18,19 +18,28 @@ export class UserManagementService {
constructor(private http: HttpClient, constructor(private http: HttpClient,
private router: Router) { private router: Router) {
this.promise = new Promise<any>((resolve => { this.promise = new Promise<any>((resolve => {
const token = COOKIE.getCookie('AccessToken'); if(properties.environment !== 'development') {
if (!token) { const token = COOKIE.getCookie('AccessToken');
this.getUserInfoSubject.next(null); if (!token) {
resolve(); this.getUserInfoSubject.next(null);
} else {
this.http.get<User>(properties.userInfoUrl + token).pipe(map(userInfo => {
return this.parseUserInfo(userInfo);
})).pipe(timeout(3000), catchError(() => {
return of(null);
})).subscribe(user => {
this.getUserInfoSubject.next(user);
resolve(); resolve();
}); } else {
this.http.get<User>(properties.userInfoUrl + token).pipe(map(userInfo => {
return this.parseUserInfo(userInfo);
})).pipe(timeout(3000), catchError(() => {
return of(null);
})).subscribe(user => {
this.getUserInfoSubject.next(user);
resolve();
});
}
} else {
if(!COOKIE.getCookie('AccessToken')) {
this.getUserInfoSubject.next(null);
resolve();
} else {
this.updateUserInfo(resolve);
}
} }
})); }));
this.router.events.subscribe(event => { this.router.events.subscribe(event => {
@ -51,6 +60,19 @@ export class UserManagementService {
} }
} }
public updateUserInfo(resolve: Function = null) {
this.http.get<User>(properties.userInfoUrl, CustomOptions.registryOptions()).pipe(map(userInfo => {
return this.parseUserInfo(userInfo);
})).pipe(timeout(3000), catchError(() => {
return of(null);
})).subscribe(user => {
this.getUserInfoSubject.next(user);
if(resolve) {
resolve();
}
});
}
private async getUserInfoAsync(): Promise<User> { private async getUserInfoAsync(): Promise<User> {
await this.promise; await this.promise;
return this.getUserInfoSubject.getValue(); return this.getUserInfoSubject.getValue();
@ -76,10 +98,12 @@ export class UserManagementService {
} }
if (info.edu_person_entitlements) { if (info.edu_person_entitlements) {
user.role = info.edu_person_entitlements; user.role = info.edu_person_entitlements;
} else if (info.roles) {
user.role = info.roles;
} else { } else {
user.role = []; user.role = [];
} }
user.expirationDate = info.exp; user.expirationDate = info.exp_date;
return user; return user;
} }
} }

View File

@ -0,0 +1,45 @@
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from "rxjs";
import {properties} from "../../../environments/environment";
import {CustomOptions} from "./servicesUtils/customOptions.class";
import {map} from "rxjs/operators";
@Injectable({
providedIn: 'root'
})
export class UserRegistryService {
constructor(private http: HttpClient) {
}
public getSubscribersCount(type: string, id: string): Observable<any> {
return this.http.get(properties.registryUrl + encodeURIComponent(type) + '/' + encodeURIComponent(id) + '/subscribers/count');
}
public subscribeTo(type: string, id: string): Observable<any> {
return this.http.post(properties.registryUrl + 'subscribe/' + encodeURIComponent(type) + '/' + encodeURIComponent(id),
null, CustomOptions.registryOptions())
}
public unsubscribeFrom(type: string, id: string): Observable<any> {
return this.http.post(properties.registryUrl + 'unsubscribe/' + encodeURIComponent(type) + '/' + encodeURIComponent(id),
null, CustomOptions.registryOptions())
}
public getSubscribers(type: string, id: string): Observable<any[]> {
return this.http.get<any>(properties.registryUrl + encodeURIComponent(type) + '/' + encodeURIComponent(id) + '/subscribers/').pipe(map(response => response.response));
}
public getManagers(type: string, id: string): Observable<any[]> {
return this.http.get<any>(properties.registryUrl + encodeURIComponent(type) + '/' + encodeURIComponent(id) + '/managers/').pipe(map(response => response.response));
}
public getSubscribersEmail(type: string, id: string): Observable<any[]> {
return this.http.get<any>(properties.registryUrl + encodeURIComponent(type) + '/' + encodeURIComponent(id) + '/subscribers/email').pipe(map(response => response.response));
}
public getManagersEmail(type: string, id: string): Observable<any[]> {
return this.http.get<any>(properties.registryUrl + encodeURIComponent(type) + '/' + encodeURIComponent(id) + '/managers/email').pipe(map(response => response.response));
}
}

View File

@ -50,6 +50,7 @@ export interface EnvProperties {
piwikBaseUrl?: string; piwikBaseUrl?: string;
piwikSiteId?: string; piwikSiteId?: string;
loginUrl?: string; loginUrl?: string;
registryUrl?: string;
logoutUrl?: string; logoutUrl?: string;
userInfoUrl?: string; userInfoUrl?: string;
cookieDomain?: string; cookieDomain?: string;