import {Injectable} from "@angular/core"; import {HttpClient} from "@angular/common/http"; import {BehaviorSubject, from, Observable, Subscriber} from "rxjs"; import { Indicator, ManageStakeholders, Section, Stakeholder, StakeholderInfo, StakeholderType, SubCategory, Umbrella, Visibility } from "../entities/stakeholder"; import {HelperFunctions} from "../../utils/HelperFunctions.class"; import {map} from "rxjs/operators"; import {properties} from "../../../../environments/environment"; import {CustomOptions} from "../../services/servicesUtils/customOptions.class"; export interface SectionInfo { id: string; indicators: string[]; } export interface MoveIndicator { target: string; from: SectionInfo; to: SectionInfo; } export interface UpdateUmbrella { type: StakeholderType; action: "ADD" | "REMOVE", child: string } @Injectable({ providedIn: "root" }) export class StakeholderService { private stakeholderSubject: BehaviorSubject = null; private promise: Promise; private sub; constructor(private http: HttpClient) { this.stakeholderSubject = new BehaviorSubject(null); } ngOnDestroy() { this.clearSubscriptions(); } clearSubscriptions() { if (this.sub instanceof Subscriber) { this.sub.unsubscribe(); } } getStakeholder(alias: string, shouldUpdate: boolean = false): Observable { if (!this.stakeholderSubject.value || this.stakeholderSubject.value.alias !== alias || shouldUpdate) { this.promise = new Promise((resolve, reject) => { this.sub = this.http.get(properties.monitorServiceAPIURL + '/stakeholder/' + encodeURIComponent(alias), CustomOptions.registryOptions()).pipe(map(stakeholder => { return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholder)); })).subscribe(stakeholder => { this.stakeholderSubject.next(stakeholder); resolve(); }, error => { this.stakeholderSubject.next(null); resolve(); }); }); } return from(this.getStakeholderAsync()); } getChildStakeholder(parent: string, type: string, child: string, shouldUpdate: boolean = false): Observable { if (!this.stakeholderSubject.value || this.stakeholderSubject.value.alias !== child || shouldUpdate) { this.promise = new Promise((resolve, reject) => { this.sub = this.http.get(properties.monitorServiceAPIURL + '/stakeholder/' + encodeURIComponent(parent) + '/' + type + '/' + encodeURIComponent(child), CustomOptions.registryOptions()).pipe(map(stakeholder => { return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholder)); })).subscribe(stakeholder => { this.stakeholderSubject.next(stakeholder); resolve(); }, error => { this.stakeholderSubject.next(null); resolve(); }); }); } return from(this.getStakeholderAsync()); } getResearcherStakeholder(orcid, name, results, shouldUpdate: boolean = false): Observable { if (!this.stakeholderSubject.value || this.stakeholderSubject.value.alias !== orcid || shouldUpdate) { this.promise = new Promise((resolve, reject) => { this.sub = this.http.get(properties.monitorServiceAPIURL + '/stakeholder/' + encodeURIComponent("researcher"), CustomOptions.registryOptions()).pipe(map(stakeholder => { return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholder)); })).subscribe(stakeholder => { stakeholder.index_id = orcid; stakeholder.index_name = name; stakeholder.name = name; stakeholder.alias = orcid; if (results < 7 && stakeholder.topics[0]?.categories[0]?.subCategories[0]) { stakeholder.topics[0].categories[0].subCategories[0].charts = []; // keep only numbers - charts wont show much anyway } this.stakeholderSubject.next(stakeholder); resolve(); }, error => { let stakeholder = new Stakeholder(null, "researcher", orcid, name, name, orcid, "PUBLIC", null, null, ""); this.stakeholderSubject.next(stakeholder); resolve(); }); }); } return from(this.getStakeholderAsync()); } async getStakeholderAsync() { if (this.promise) { await this.promise; this.promise = null; } this.clearSubscriptions(); return this.stakeholderSubject.getValue(); } getAlias(url: string): Observable { return this.http.get(url + '/stakeholder/alias', CustomOptions.registryOptions()).pipe(map(stakeholders => { return HelperFunctions.copy(stakeholders); })); } getStakeholders(url: string, type: string = null, defaultId: string = null): Observable<(Stakeholder & StakeholderInfo)[]> { return this.http.get(url + '/stakeholder' + ((type) ? ('?type=' + type) : '') + ((!type && defaultId) ? ('?defaultId=' + defaultId) : ''), CustomOptions.registryOptions()).pipe(map(stakeholders => { return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholders)); })); } getMyStakeholders(url: string, type: string = null): Observable { return this.http.get(url + '/my-stakeholder' + ((type) ? ('?type=' + type) : ''), CustomOptions.registryOptions()).pipe(map(manageStakeholder => { return HelperFunctions.copy({ templates: Stakeholder.checkIsUpload(manageStakeholder.templates), standalone: Stakeholder.checkIsUpload(manageStakeholder.standalone), dependent: Stakeholder.checkIsUpload(manageStakeholder.dependent), umbrella: Stakeholder.checkIsUpload(manageStakeholder.umbrella), }); })); } buildStakeholder(url: string, stakeholder: Stakeholder, copyId: string, standalone: boolean = true, umbrella: boolean = false): Observable { if (stakeholder.alias && stakeholder.alias.startsWith('/')) { stakeholder.alias = stakeholder.alias.slice(1); } let buildStakeholder = { stakeholder: stakeholder, copyId: copyId, umbrella: umbrella, standalone: standalone } return this.http.post(url + '/build-stakeholder', buildStakeholder, CustomOptions.registryOptions()).pipe(map(stakeholder => { return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholder)); })); } changeVisibility(url: string, path: string[], visibility: Visibility, propagate: boolean = false): Observable { return this.http.post(url + '/' + path.join('/') + '/change-visibility' + '?visibility=' + visibility + (propagate ? '&propagate=true' : ''), null, CustomOptions.registryOptions()); } saveElement(url: string, element: any, path: string[] = [], isFull: boolean = false): Observable { if (element.alias && element.alias.startsWith('/')) { element.alias = element.alias.slice(1); } return this.http.post(url + ((path.length > 0) ? '/' : '') + path.join('/') + '/save' + (isFull ? '/full' : ''), element, CustomOptions.registryOptions()).pipe(map(element => { if (path.length === 0) { return HelperFunctions.copy(Stakeholder.checkIsUpload(element)); } else { return HelperFunctions.copy(element); } })); } saveBulkElements(url: string, indicators, path: string[] = []): Observable { return this.http.post(url + ((path.length > 0) ? '/' : '') + path.join('/') + '/save-bulk', indicators, CustomOptions.registryOptions()).pipe(map(element => { if (path.length === 0) { return HelperFunctions.copy(Stakeholder.checkIsUpload(element)); } else { return HelperFunctions.copy(element); } })); } saveSection(url: string, element: any, path: string[] = [], index: number = -1): Observable
{ return this.http.post
(url + ((path.length > 0) ? '/' : '') + path.join('/') + '/save/' + index, element, CustomOptions.registryOptions()).pipe(map(element => { return HelperFunctions.copy(element); })); } deleteElement(url: string, path: string[], childrenAction: string = null): Observable { let params: string = ""; if (childrenAction) { params = "?children=" + childrenAction; } return this.http.delete(url + '/' + path.join('/') + '/delete' + params, CustomOptions.registryOptions()); } reorderElements(url: string, path: string[], ids: string[]): Observable { return this.http.post(url + '/' + path.join('/') + '/reorder', ids, CustomOptions.registryOptions()); } reorderIndicators(url: string, path: string[], indicators: string[]): Observable { return this.http.post(url + '/' + path.join('/') + '/reorder', indicators, CustomOptions.registryOptions()).pipe(map(indicators => { return HelperFunctions.copy(indicators); })); } moveIndicator(url: string, path: string[], moveIndicator: MoveIndicator): Observable { return this.http.post(url + '/' + path.join('/') + '/moveIndicator', moveIndicator, CustomOptions.registryOptions()).pipe(map(subCategory => { return HelperFunctions.copy(subCategory); })); } updateUmbrella(url: string, id: string, update: UpdateUmbrella): Observable { return this.http.post(url + '/' + id + '/umbrella', update, CustomOptions.registryOptions()).pipe(map(umbrella => { return HelperFunctions.copy(umbrella); })); } getStakeholderAsObservable(): Observable { return this.stakeholderSubject.asObservable(); } setStakeholder(stakeholder: Stakeholder) { this.stakeholderSubject.next(stakeholder); } }