diff --git a/monitor/entities/stakeholder.ts b/monitor/entities/stakeholder.ts new file mode 100644 index 00000000..f83f26f8 --- /dev/null +++ b/monitor/entities/stakeholder.ts @@ -0,0 +1,203 @@ +import {SafeResourceUrl} from "@angular/platform-browser"; + +export const ChartHelper = { + prefix: "((__", + suffix: "__))" +}; + +export type StakeholderType = 'funder' | 'ri' | 'project' | 'organization'; +export type IndicatorType = 'number' | 'chart'; +export type IndicatorWidth = 'small' | 'medium' | 'large'; +export type IndicatorPathType = 'table' | 'bar' | 'column' | 'pie' | 'line' | 'other'; +export type SourceType = 'statistics' | 'search' | 'metrics' | 'stats-tool' | 'old' | 'image'; + +export class Stakeholder { + _id: string; + type: StakeholderType; + name: string; + index_id; + index_name: string; + index_shortName: string; + alias: string; + defaultId: string; + isActive: boolean; + isPublic: boolean; + creationDate: Date = null; + updateDate: Date; + managers: string[]; + logoUrl:string; + topics: Topic[]; + + constructor(id: string, type: StakeholderType, index_id, index_name: string, index_shortName: string, alias: string, isActive: boolean, isPublic: boolean, logoUrl:string, defaultId: string = null) { + this.initializeFunder(id, type, index_id, index_name, index_shortName, defaultId, alias, isActive, isPublic, logoUrl); + this.topics = []; + this.managers = []; + } + + initializeFunder(id: string, type: StakeholderType, index_id, index_name: string, index_shortName: string, defaultId: string, alias: string, isActive: boolean, isPublic: boolean, logoUrl:string) { + this._id = id; + this.type = type; + this.index_id = index_id; + this.index_name = index_name; + this.index_shortName = index_shortName; + this.defaultId = defaultId; + this.alias = alias; + this.isActive = isActive; + this.isPublic = isPublic; + this.logoUrl = logoUrl; + } +} + +export class Topic { + _id: string; + name: string; + alias: string; + description: string; + isActive: boolean; + isPublic: boolean; + defaultId: string; + categories: Category[]; + + constructor(name: string, description: string, alias: string, isActive: boolean, isPublic: boolean, defaultId: string = null) { + this._id = null; + this.name = name; + this.description = description; + this.alias = alias; + this.isActive = isActive; + this.isPublic = isPublic; + this.defaultId = defaultId; + this.categories = []; + } +} + +export class Category { + _id: string; + name: string; + alias: string; + description: string; + isActive: boolean; + isPublic: boolean; + defaultId: string; + subCategories: SubCategory[]; + + constructor(name: string, description: string, alias: string, isActive: boolean, isPublic: boolean, defaultId: string = null) { + this._id = null; + this.name = name; + this.description = description; + this.alias = alias; + this.isActive = isActive; + this.isPublic = isPublic; + this.defaultId = defaultId; + this.subCategories = []; + } +} + +export class SubCategory { + _id: string; + name: string; + alias: string; + description: string; + isActive: boolean; + isPublic: boolean; + defaultId: string; + charts: Section[]; + numbers: Section[]; + recommendedFor:string[]; + + constructor(name: string, description: string, alias: string, isActive: boolean, isPublic: boolean, defaultId: string = null) { + this._id = null; + this.name = name; + this.description = description; + this.alias = alias; + this.isActive = isActive; + this.isPublic = isPublic; + this.defaultId = defaultId; + this.charts = []; + this.numbers = []; + this.recommendedFor= []; + } + +} + +export class Section { + _id: string; + title: string; + defaultId: string; + stakeholderAlias: string; + type: IndicatorType; + indicators: Indicator[]; + + constructor(type: IndicatorType, title: string = null, defaultId: string = null, stakeholderAlias: string = null) { + this._id = null; + this.title = title; + this.type = type; + this.defaultId = defaultId; + this.stakeholderAlias = stakeholderAlias; + this.indicators = []; + } +} + +export class Indicator { + _id: string; + name: string; + description: string; + type: IndicatorType; + width: IndicatorWidth; + tags: string[]; + isActive: boolean; + isPublic: boolean; + defaultId: string; + indicatorPaths: IndicatorPath[]; + recommendedFor:string[]; + + constructor(name: string, description: string, type: IndicatorType, width: IndicatorWidth, isActive: boolean, isPublic: boolean, indicatorPaths: IndicatorPath[], defaultId: string = null) { + this._id = null; + this.name = name; + this.description = description; + this.type = type; + this.width = width; + this.isActive = isActive; + this.isPublic = isPublic; + this.defaultId = defaultId; + this.indicatorPaths = indicatorPaths; + this.recommendedFor = []; + } + +} + +export class IndicatorPath { + type: IndicatorPathType; + source: SourceType; + url: string; + safeResourceUrl: SafeResourceUrl; // initialize on front end + jsonPath: string[]; + chartObject: string; + parameters: any; + filters: any; + + constructor(type: IndicatorPathType, source: SourceType, url: string, chartObject: string, jsonPath: string[]) { + this.type = type; + this.url = url; + this.source = source; + this.jsonPath = jsonPath; + this.chartObject = chartObject; + this.parameters = {}; + this.filters = {}; + } + + static createParameters(funderName: string = null, title: string = null, chartType: string = null): any { + return { + index_name: funderName, + title: title, + type: chartType + }; + } + + static createResultFilters(dbType: string = null): any { + return { + fundingL0: '{"groupFilters":[{"field":"' + dbType + '.project.funding level 0","type":"=","values":["' + ChartHelper.prefix + 'fundingL0' + ChartHelper.suffix + '"]}],"op":"AND"}', + start_year: '{"groupFilters":[{"field":"' + dbType + '.year","type":">=","values":["' + ChartHelper.prefix + 'start_year' + ChartHelper.suffix + '"]}],"op":"AND"}', + end_year: '{"groupFilters":[{"field":"' + dbType + '.year","type":"<=","values":["' + ChartHelper.prefix + 'end_year' + ChartHelper.suffix + '"]}],"op":"AND"}' + }; + } +} diff --git a/monitor/services/stakeholder.service.ts b/monitor/services/stakeholder.service.ts new file mode 100644 index 00000000..b95fac2f --- /dev/null +++ b/monitor/services/stakeholder.service.ts @@ -0,0 +1,113 @@ +import {Injectable} from "@angular/core"; +import {HttpClient} from "@angular/common/http"; +import {BehaviorSubject, Observable} from "rxjs"; +import {Indicator, IndicatorPath, Section, Stakeholder} from "../entities/stakeholder"; +import {HelperFunctions} from "../../utils/HelperFunctions.class"; +import {map} from "rxjs/operators"; +import {StakeholderCreator} from "../../../utils/entities/stakeholderCreator"; + +let maps: string[] = ['parameters', 'filters']; + +@Injectable({ + providedIn: "root" +}) +export class StakeholderService { + + private stakeholderSubject: BehaviorSubject = null; + + constructor(private http: HttpClient) { + this.stakeholderSubject = new BehaviorSubject(null); + } + + getStakeholder(url: string, alias:string): Observable { + /*return new BehaviorSubject( + StakeholderCreator.createFunderFromDefaultProfile("ec","funder","ec__________::EC", + "European Commission","EC", + false,"ec",true,true)).asObservable();*/ + return this.http.get(url + '/stakeholder/' + encodeURIComponent(alias)).pipe(map(stakeholder => { + return this.formalize(stakeholder); + })); + } + + getAllStakeholders(url: string, type: string = null): Observable { + return this.http.get(url + '/stakeholder/all' + ((type)?('?type=' + type):'')).pipe(map(stakeholders => { + return this.formalize(stakeholders); + })); + } + + getStakeholders(url: string, type: string = null): Observable { + return this.http.get(url + '/stakeholder' + ((type)?('?type=' + type):'')).pipe(map(stakeholders => { + return this.formalize(stakeholders); + })); + } + + getDefaultStakeholders(url: string, type: string = null): Observable { + return this.http.get(url + '/stakeholder/default' + ((type)?('?type=' + type):'')).pipe(map(stakeholders => { + return this.formalize(stakeholders); + })); + } + + buildStakeholder(url: string, stakeholder: Stakeholder): Observable { + return this.http.post(url + '/build-stakeholder', stakeholder).pipe(map(stakeholder => { + return this.formalize(stakeholder); + })); + } + + saveStakeholder(url: string, stakeholder: Stakeholder): Observable { + return this.http.post(url + '/stakeholder/save', stakeholder).pipe(map(stakeholder => { + return this.formalize(stakeholder); + })); + } + + toggleStatus(url: string, path: string[]): Observable { + return this.http.post(url + '/' + path.join('/') + '/toggle-status', null); + } + + toggleAccess(url: string, path: string[]): Observable { + return this.http.post(url + '/' + path.join('/') + '/toggle-access', null); + } + + saveElement(url: string, element: any, path: string[] = []): Observable { + path = HelperFunctions.encodeArray(path); + return this.http.post(url + ((path.length > 0)?'/':'') + path.join('/') + + '/save', element).pipe(map(element => { + return this.formalize(element); + })); + } + + saveSection(url: string, element: any, path: string[] = [], index: number = -1): Observable
{ + path = HelperFunctions.encodeArray(path); + return this.http.post
(url + ((path.length > 0)?'/':'') + path.join('/') + + '/save/' + index, element).pipe(map(element => { + return this.formalize(element); + })); + } + + deleteElement(url: string, path: string[]): Observable { + path = HelperFunctions.encodeArray(path); + return this.http.delete(url + '/' + path.join('/') + '/delete'); + } + + reorderIndicators(url: string, path: string[], indicatorIds: string[], type: string = 'chart'): Observable { + path = HelperFunctions.encodeArray(path); + return this.http.post(url + '/' + path.join('/') + '/' + type + '/reorder', indicatorIds).pipe(map(indicators => { + return this.formalize(indicators); + })); + } + + getStakeholderAsObservable(): Observable { + return this.stakeholderSubject.asObservable(); + } + + get stakeholder(): Stakeholder { + return this.stakeholderSubject.getValue(); + } + + setStakeholder(stakeholder: Stakeholder) { + this.stakeholderSubject.next(stakeholder); + } + + private formalize(element: any) { + return HelperFunctions.copy(element); + } +}