[Monitor Dashboard]: 1. Create indicator Modal 2. Add new fields on stakeholder elements. 3. Add getFullUrl on indicatorUtils.

git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-monitor-portal/trunk/monitor_dashboard@57639 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
Konstantinos Triantafyllou 2019-11-19 14:25:19 +00:00
parent 0738f2eed7
commit ea9e6f3d9b
13 changed files with 369 additions and 116 deletions

View File

@ -65,7 +65,7 @@
<hr> <hr>
<div class="uk-grid-small uk-child-width-1-2" uk-grid> <div class="uk-grid-small uk-child-width-1-2" uk-grid>
<div> <div>
<button class="md-btn md-btn-small" (click)="deleteTopicOpen(editTopic, i)">Delete</button> <button class="md-btn md-btn-small" (click)="deleteTopicOpen(copyTopic.name, editTopic, i)">Delete</button>
</div> </div>
<div> <div>
<button class="md-btn md-btn-small md-btn-primary uk-float-right" <button class="md-btn md-btn-small md-btn-primary uk-float-right"

View File

@ -116,12 +116,10 @@ export class HomeComponent implements OnInit, OnDestroy {
} }
} }
public deleteTopicOpen(element, index: number) { public deleteTopicOpen(name: string, element, index: number) {
this.element = element; this.element = element;
this.index = index; this.index = index;
this.deleteTopicModal.alertHeader = true; this.deleteTopicModal.alertTitle = 'Delete ' + name;
this.deleteTopicModal.alertMessage = true;
this.deleteTopicModal.cancelButton = true;
this.deleteTopicModal.cancelButtonText = 'No'; this.deleteTopicModal.cancelButtonText = 'No';
this.deleteTopicModal.okButtonText = 'Yes'; this.deleteTopicModal.okButtonText = 'Yes';
this.deleteTopicModal.message = 'This topic will permanently be deleted. Are you sure you want to proceed?'; this.deleteTopicModal.message = 'This topic will permanently be deleted. Are you sure you want to proceed?';

View File

@ -3,6 +3,7 @@ import {HttpClient} from "@angular/common/http";
import {BehaviorSubject, Observable} from "rxjs"; import {BehaviorSubject, Observable} from "rxjs";
import {Indicator, Stakeholder} from "../utils/entities/stakeholder"; import {Indicator, Stakeholder} from "../utils/entities/stakeholder";
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class"; import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
import {map} from "rxjs/operators";
@Injectable({ @Injectable({
providedIn: "root" providedIn: "root"
@ -17,23 +18,33 @@ export class StakeholderService {
getStakeholder(url: string, alias:string): Observable<Stakeholder> { getStakeholder(url: string, alias:string): Observable<Stakeholder> {
// return new BehaviorSubject<Stakeholder>(Stakeholder.createECStakeholder()).asObservable(); // return new BehaviorSubject<Stakeholder>(Stakeholder.createECStakeholder()).asObservable();
return this.http.get<Stakeholder>(url + '/stakeholder/' + encodeURIComponent(alias)); return this.http.get<Stakeholder>(url + '/stakeholder/' + encodeURIComponent(alias)).pipe(map(stakeholder => {
return this.formalizeStakeholder([stakeholder])[0];
}));
} }
getAllStakeholders(url: string, type: string = null): Observable<Stakeholder[]> { getAllStakeholders(url: string, type: string = null): Observable<Stakeholder[]> {
return this.http.get<Stakeholder[]>(url + '/stakeholder/all' + (type)?('?type=' + type):''); return this.http.get<Stakeholder[]>(url + '/stakeholder/all' + (type)?('?type=' + type):'').pipe(map(stakeholders => {
return this.formalizeStakeholder(stakeholders);
}));
} }
getStakeholders(url: string, type: string = null): Observable<Stakeholder[]> { getStakeholders(url: string, type: string = null): Observable<Stakeholder[]> {
return this.http.get<Stakeholder[]>(url + '/stakeholder' + (type)?('?type=' + type):''); return this.http.get<Stakeholder[]>(url + '/stakeholder' + (type)?('?type=' + type):'').pipe(map(stakeholders => {
return this.formalizeStakeholder(stakeholders);
}));
} }
getDefaultStakeholders(url: string, type: string = null): Observable<Stakeholder[]> { getDefaultStakeholders(url: string, type: string = null): Observable<Stakeholder[]> {
return this.http.get<Stakeholder[]>(url + '/stakeholder/default' + (type)?('?type=' + type):''); return this.http.get<Stakeholder[]>(url + '/stakeholder/default' + (type)?('?type=' + type):'').pipe(map(stakeholders => {
return this.formalizeStakeholder(stakeholders);
}));
} }
saveStakeholder(url: string, stakeholder: Stakeholder): Observable<Stakeholder> { saveStakeholder(url: string, stakeholder: Stakeholder): Observable<Stakeholder> {
return this.http.post<Stakeholder>(url + '/stakeholder/save', stakeholder); return this.http.post<Stakeholder>(url + '/stakeholder/save', stakeholder).pipe(map(stakeholder => {
return this.formalizeStakeholder([stakeholder])[0];
}));
} }
saveIndicator(url: string, path: string[], indicator: Indicator): Observable<Indicator> { saveIndicator(url: string, path: string[], indicator: Indicator): Observable<Indicator> {
@ -58,4 +69,30 @@ export class StakeholderService {
setStakeholder(stakeholder: Stakeholder) { setStakeholder(stakeholder: Stakeholder) {
this.stakeholderSubject.next(stakeholder); this.stakeholderSubject.next(stakeholder);
} }
private formalizeStakeholder(stakeholders: Stakeholder[]): Stakeholder[] {
stakeholders.forEach( stakeholder => {
stakeholder.topics.forEach( topic => {
topic.categories.forEach( category => {
category.subCategories.forEach(subcategory => {
subcategory.charts.forEach(indicator => {
indicator.indicatorPaths.forEach(indicatorPath => {
if(indicatorPath.parameters) {
indicatorPath.parameters = new Map<string, string>(Object.entries(indicatorPath.parameters));
}
if(indicatorPath.filters) {
let filters = new Map<string, Map<string, string>>();
Object.entries(indicatorPath.filters).forEach(([key, value]) => {
filters.set(key, new Map<string, string>(Object.entries(value)));
});
indicatorPath.filters = filters;
}
});
});
});
});
});
});
return stakeholders;
}
} }

View File

@ -73,11 +73,12 @@
<div [class.uk-child-width-1-3@m]="grid" <div [class.uk-child-width-1-3@m]="grid"
[class.uk-child-width-1-2@s]="grid" [class.uk-child-width-1-2@s]="grid"
[class.uk-child-width-1-1]="!grid" [class.uk-child-width-1-1]="!grid"
class="uk-grid-match" class="uk-grid-match uk-grid-small"
[class.list]="!grid"
uk-grid> uk-grid>
<ng-template ngFor [ngForOf]="displayNumbers" let-indicator let-i="index"> <ng-template ngFor [ngForOf]="displayNumbers" let-indicator let-i="index">
<div> <div>
<div class="md-card" [class.uk-width-4-5@xl]="!grid"> <div class="md-card">
<div class="md-card-toolbar"> <div class="md-card-toolbar">
<div class="md-card-toolbar-actions" [class.uk-flex-middle]="!grid" [class.uk-flex]="!grid"> <div class="md-card-toolbar-actions" [class.uk-flex-middle]="!grid" [class.uk-flex]="!grid">
<span *ngIf="!grid" class="uk-margin-medium-right uk-flex uk-flex-middle"> <span *ngIf="!grid" class="uk-margin-medium-right uk-flex uk-flex-middle">
@ -118,11 +119,12 @@
<div [class.uk-child-width-1-3@m]="grid" <div [class.uk-child-width-1-3@m]="grid"
[class.uk-child-width-1-2@s]="grid" [class.uk-child-width-1-2@s]="grid"
[class.uk-child-width-1-1]="!grid" [class.uk-child-width-1-1]="!grid"
uk-height-match="target: .md-card" [class.list]="!grid"
class="uk-grid-match uk-grid-small"
uk-grid> uk-grid>
<ng-template ngFor [ngForOf]="displayCharts" let-indicator let-i="index"> <ng-template ngFor [ngForOf]="displayCharts" let-indicator let-i="index">
<div> <div>
<div class="md-card" [class.uk-width-4-5@xl]="!grid"> <div class="md-card">
<div class="md-card-toolbar"> <div class="md-card-toolbar">
<div class="md-card-toolbar-actions" [class.uk-flex-middle]="!grid" [class.uk-flex]="!grid"> <div class="md-card-toolbar-actions" [class.uk-flex-middle]="!grid" [class.uk-flex]="!grid">
<ng-template [ngIf]="!grid"> <ng-template [ngIf]="!grid">
@ -154,7 +156,7 @@
<div *ngIf="grid" class="md-card-content"> <div *ngIf="grid" class="md-card-content">
<div class="uk-flex uk-flex-center" uk-grid> <div class="uk-flex uk-flex-center" uk-grid>
<div class="uk-width-1-1"> <div class="uk-width-1-1">
{{indicator.description}} {{indicator.description ? indicator.description : ''}}
</div> </div>
<div class="uk-width-1-3 uk-text-center" <div class="uk-width-1-3 uk-text-center"
[ngClass]="'uk-child-width-1-' + indicator.indicatorPaths.length" uk-grid> [ngClass]="'uk-child-width-1-' + indicator.indicatorPaths.length" uk-grid>
@ -182,6 +184,77 @@
</div> </div>
</div> </div>
</ng-template> </ng-template>
<div>
<div class="md-card clickable" (click)="createIndicatorOpen()">
<div class="md-card-toolbar">
<div class="md-card-toolbar-heading-text"
[class.uk-flex-middle]="!grid"
[class.uk-flex]="!grid"
[class.uk-flex-center]="!grid">
<i *ngIf="!grid" class="material-icons md-36">add</i>
<span>Create a custom Indicator</span>
</div>
</div>
<div *ngIf="grid" class="md-card-content">
<div class="uk-flex uk-flex-center" uk-grid>
<div class="uk-width-1-1">
Use our advance tool to create a custom Indicator that suit the needs of your funding KPI's.
</div>
</div>
<div class="uk-flex uk-flex-center uk-margin-top">
<i class="material-icons md-48">add</i>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
<modal-alert #createIndicatorModal
(alertOutput)="createIndicator()"
[okDisabled]="indicatorFb && indicatorFb.invalid">
<div *ngIf="indicatorFb" class="uk-form-stacked" [formGroup]="indicatorFb">
<label class="uk-form-label">Name</label>
<div class="uk-form-controls" formArrayName="name">
<input class="uk-input"
[class.uk-form-danger]="indicatorFb.get('name').invalid && indicatorFb.get('name').dirty"
[formControl]="indicatorFb.get('name')">
</div>
<label class="uk-form-label">Description</label>
<div class="uk-form-controls" formArrayName="urls">
<textarea class="uk-textarea" rows="3"
[formControl]="indicatorFb.get('description')"></textarea>
</div>
<label class="uk-form-label">Chart url</label>
<div class="uk-form-controls" formArrayName="urls">
<input class="uk-input"
[class.uk-form-danger]="chartUrl.invalid && chartUrl.dirty"
*ngFor="let chartUrl of urls.controls;"
[formControl]="chartUrl">
</div>
</div>
</modal-alert>
<!--<modal-alert #editIndicatorModal
(alertOutput)="saveIndicator()"
[okDisabled]="editIndicatorFb && (editIndicatorFb.invalid || !editIndicatorFb.dirty)">
<div *ngIf="editIndicatorFb" class="uk-form-stacked" [formGroup]="editIndicatorFb">
<label class="uk-form-label">Name</label>
<div class="uk-form-controls" formArrayName="name">
<input class="uk-input"
[class.uk-form-danger]="indicatorFb.get('name').status === 'INVALID' && indicatorFb.get('name').dirty"
[formControl]="indicatorFb.get('name')">
</div>
<label class="uk-form-label">Description</label>
<div class="uk-form-controls" formArrayName="urls">
<textarea class="uk-textarea" rows="3"
[formControl]="indicatorFb.get('description')"></textarea>
</div>
<label class="uk-form-label">Chart url</label>
<div class="uk-form-controls" formArrayName="urls">
<input class="uk-input"
[class.uk-form-danger]="chartUrl.status === 'INVALID' && chartUrl.dirty"
*ngFor="let chartUrl of urls.controls;"
[formControl]="chartUrl">
</div>
</div>
</modal-alert>-->

View File

@ -1,7 +1,11 @@
import {Component, Input, OnChanges, OnInit, SimpleChanges} from "@angular/core"; import {Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from "@angular/core";
import {SideBarService} from "../library/sharedComponents/sidebar/sideBar.service"; import {SideBarService} from "../library/sharedComponents/sidebar/sideBar.service";
import {Indicator, Stakeholder} from "../utils/entities/stakeholder"; import {Indicator, Stakeholder} from "../utils/entities/stakeholder";
import {IndicatorUtils} from "../utils/indicator-utils"; import {IndicatorUtils} from "../utils/indicator-utils";
import {FormArray, FormBuilder, FormGroup, Validators} from "@angular/forms";
import {AlertModal} from "../openaireLibrary/utils/modal/alert";
import {StatisticsService} from "../utils/services/statistics.service";
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
@Component({ @Component({
selector: 'indicators', selector: 'indicators',
@ -18,6 +22,12 @@ export class IndicatorsComponent implements OnInit, OnChanges {
@Input() @Input()
public stakeholder: Stakeholder = null; public stakeholder: Stakeholder = null;
public indicatorUtils: IndicatorUtils = new IndicatorUtils(); public indicatorUtils: IndicatorUtils = new IndicatorUtils();
public indicatorFb: FormGroup;
public editIndicatorFb: FormGroup;
/**
* Editable indicator
*/
public indicator: Indicator;
/** /**
* All charts and numbers * All charts and numbers
*/ */
@ -40,22 +50,27 @@ export class IndicatorsComponent implements OnInit, OnChanges {
*/ */
public grid: boolean = true; public grid: boolean = true;
constructor(private sideBarService: SideBarService) {} @ViewChild('createIndicatorModal') createIndicatorModal: AlertModal;
@ViewChild('editIndicatorModal') editIndicatorModal: AlertModal;
constructor(private sideBarService: SideBarService,
private statisticsService: StatisticsService,
private fb: FormBuilder) {
}
ngOnInit(): void { ngOnInit(): void {
} }
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
if(this.canEdit) { if (this.canEdit) {
this.charts = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]. this.charts = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].charts;
subCategories[this.subcategoryIndex].charts; console.log(this.charts);
this.displayCharts = this.filterChartType(this.filterPrivacy( this.displayCharts = this.filterChartType(this.filterPrivacy(
this.filterStatus(this.filterByKeyword(this.charts, this.keyword), this.status), this.filterStatus(this.filterByKeyword(this.charts, this.keyword), this.status),
this.privacy), this.privacy),
this.chartType this.chartType
); );
this.numbers = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]. this.numbers = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].numbers;
subCategories[this.subcategoryIndex].numbers;
this.displayNumbers = this.filterPrivacy(this.filterStatus( this.displayNumbers = this.filterPrivacy(this.filterStatus(
this.filterByKeyword(this.numbers, this.keyword), this.filterByKeyword(this.numbers, this.keyword),
this.status), this.status),
@ -63,6 +78,18 @@ export class IndicatorsComponent implements OnInit, OnChanges {
} }
} }
public toggleOpen(event = null) {
if (!event) {
this.sideBarService.setOpen(!this.open);
} else if (event && event['value'] === true) {
this.sideBarService.setOpen(false);
}
}
public changeGrid(value) {
this.grid = value;
}
onChartTypeChange(value) { onChartTypeChange(value) {
this.displayCharts = this.filterChartType(this.charts, value); this.displayCharts = this.filterChartType(this.charts, value);
} }
@ -82,7 +109,7 @@ export class IndicatorsComponent implements OnInit, OnChanges {
this.displayNumbers = this.filterByKeyword(this.numbers, value); this.displayNumbers = this.filterByKeyword(this.numbers, value);
} }
filterChartType(indicators: Indicator[], value): Indicator[] { private filterChartType(indicators: Indicator[], value): Indicator[] {
if (value === 'all') { if (value === 'all') {
return indicators; return indicators;
} else { } else {
@ -91,7 +118,7 @@ export class IndicatorsComponent implements OnInit, OnChanges {
} }
} }
filterPrivacy(indicators: Indicator[], value): Indicator[] { private filterPrivacy(indicators: Indicator[], value): Indicator[] {
if (value === 'all') { if (value === 'all') {
return indicators; return indicators;
} else { } else {
@ -99,7 +126,7 @@ export class IndicatorsComponent implements OnInit, OnChanges {
} }
} }
filterStatus(indicators: Indicator[], value): Indicator[] { private filterStatus(indicators: Indicator[], value): Indicator[] {
if (value === 'all') { if (value === 'all') {
return indicators; return indicators;
} else { } else {
@ -107,7 +134,7 @@ export class IndicatorsComponent implements OnInit, OnChanges {
} }
} }
filterByKeyword(indicators: Indicator[], value): Indicator[] { private filterByKeyword(indicators: Indicator[], value): Indicator[] {
if (value === null || value === '') { if (value === null || value === '') {
return indicators; return indicators;
} else { } else {
@ -126,15 +153,78 @@ export class IndicatorsComponent implements OnInit, OnChanges {
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]; this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex];
} }
public toggleOpen(event = null) { public get urls(): FormArray {
if (!event) { return this.indicatorFb.get('urls') as FormArray;
this.sideBarService.setOpen(!this.open);
} else if (event && event['value'] === true) {
this.sideBarService.setOpen(false);
}
} }
public changeGrid(value) { public addUrl() {
this.grid = value; this.urls.push(this.fb.control('', [Validators.required,
Validators.pattern('https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.' +
'[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.' +
'[a-zA-Z0-9]+\.[^\s]{2,}')])
);
}
public createIndicatorOpen() {
this.indicatorFb = this.fb.group({
name: this.fb.control('', Validators.required),
description: this.fb.control(''),
width: this.fb.control('small', Validators.required),
urls: this.fb.array([]),
});
this.addUrl();
this.createIndicatorModal.alertTitle = 'Create a new chart Indicator';
this.createIndicatorModal.cancelButtonText = 'Cancel';
this.createIndicatorModal.okButtonText = 'Create';
this.createIndicatorModal.okButtonLeft = false;
this.createIndicatorModal.alertMessage = false;
this.createIndicatorModal.open();
}
public createIndicator() {
this.indicator = new Indicator(
this.indicatorFb.value.name,
this.indicatorFb.value.description,
'chart',
this.indicatorFb.value.width,
false,
false,
[]
);
this.indicatorFb.value.urls.forEach(url => {
this.indicator.indicatorPaths.push(
this.indicatorUtils.generateIndicatorByChartUrl(this.statisticsService.getChartSource(url), url));
});
let index = this.charts.push(this.indicator);
this.editIndicatorOpen(index -1);
}
public editIndicatorOpen(index: number) {
this.indicator = HelperFunctions.copy(this.charts[index]);
let indicatorPaths = this.fb.array([]);
this.indicator.indicatorPaths.forEach(indicatorPath => {
indicatorPaths.push(this.fb.group({
parameters: this.fb.array([])
}));
});
this.editIndicatorFb = this.fb.group({
name: this.fb.control(this.indicator.name, Validators.required),
description: this.fb.control(this.indicator.description),
isPublic: this.fb.control(this.indicator.isPublic),
isActive: this.fb.control(this.indicator.isActive),
indicatorPaths: indicatorPaths,
width: this.fb.control(this.indicator.width, Validators.required),
});
console.log(this.editIndicatorFb.value);
/*this.editIndicatorModal.alertTitle = this.indicator.name;
this.editIndicatorModal.cancelButtonText = 'Cancel';
this.editIndicatorModal.okButtonText = 'Save Changes';
this.editIndicatorModal.okButtonLeft = false;
this.editIndicatorModal.alertMessage = false;
this.editIndicatorModal.open();*/
}
saveIndicator() {
} }
} }

View File

@ -54,7 +54,7 @@
<hr> <hr>
<div class="uk-grid-small uk-child-width-1-2" uk-grid> <div class="uk-grid-small uk-child-width-1-2" uk-grid>
<div> <div>
<button class="md-btn md-btn-small" (click)="deleteTopicOpen(editTopic)">Delete</button> <button class="md-btn md-btn-small" (click)="deleteTopicOpen(topic.name, editTopic)">Delete</button>
</div> </div>
<div> <div>
<button class="md-btn md-btn-small md-btn-primary uk-float-right" <button class="md-btn md-btn-small md-btn-primary uk-float-right"
@ -114,7 +114,7 @@
<hr> <hr>
<div class="uk-grid-small uk-child-width-1-2" uk-grid> <div class="uk-grid-small uk-child-width-1-2" uk-grid>
<div> <div>
<button class="md-btn md-btn-small" (click)="deleteCategoryOpen(editCategory, i)">Delete</button> <button class="md-btn md-btn-small" (click)="deleteCategoryOpen(copyCategory.name, editCategory, i)">Delete</button>
</div> </div>
<div> <div>
<button class="md-btn md-btn-small md-btn-primary uk-float-right" <button class="md-btn md-btn-small md-btn-primary uk-float-right"
@ -171,7 +171,7 @@
<hr> <hr>
<div class="uk-grid-small uk-child-width-1-2" uk-grid> <div class="uk-grid-small uk-child-width-1-2" uk-grid>
<div> <div>
<button class="md-btn md-btn-small" (click)="deleteSubcategoryOpen(editSubCategory, j)">Delete</button> <button class="md-btn md-btn-small" (click)="deleteSubcategoryOpen(copySubCategory.name, editSubCategory, j)">Delete</button>
</div> </div>
<div> <div>
<button class="md-btn md-btn-small md-btn-primary uk-float-right" <button class="md-btn md-btn-small md-btn-primary uk-float-right"

View File

@ -119,8 +119,8 @@ export class TopicComponent implements OnInit, OnDestroy {
} }
} }
public deleteTopicOpen(element) { public deleteTopicOpen(name: string, element) {
this.deleteOpen('topic', this.deleteTopicModal, element, this.topicIndex); this.deleteOpen(name,'topic', this.deleteTopicModal, element, this.topicIndex);
} }
public deleteTopic() { public deleteTopic() {
@ -177,8 +177,8 @@ export class TopicComponent implements OnInit, OnDestroy {
} }
} }
public deleteCategoryOpen(element, index) { public deleteCategoryOpen(name: string, element, index) {
this.deleteOpen('category', this.deleteCategoryModal, element, index); this.deleteOpen(name,'category', this.deleteCategoryModal, element, index);
} }
public deleteCategory() { public deleteCategory() {
@ -224,8 +224,8 @@ export class TopicComponent implements OnInit, OnDestroy {
} }
} }
public deleteSubcategoryOpen(element, index) { public deleteSubcategoryOpen(name: string, element, index) {
this.deleteOpen('subcategory', this.deleteSubcategoryModal, element, index); this.deleteOpen(name,'subcategory', this.deleteSubcategoryModal, element, index);
} }
public deleteSubcategory() { public deleteSubcategory() {
@ -242,12 +242,10 @@ export class TopicComponent implements OnInit, OnDestroy {
this.router.navigate(['/error'], {queryParams: {'page': this.router.url}}); this.router.navigate(['/error'], {queryParams: {'page': this.router.url}});
} }
private deleteOpen(type: string, modal: AlertModal, element, index) { private deleteOpen(name: string, type: string, modal: AlertModal, element, index) {
this.element = element; this.element = element;
this.index = index; this.index = index;
modal.alertHeader = true; modal.alertTitle = 'Delete ' + name;
modal.alertMessage = true;
modal.cancelButton = true;
modal.cancelButtonText = 'No'; modal.cancelButtonText = 'No';
modal.okButtonText = 'Yes'; modal.okButtonText = 'Yes';
modal.message = 'This ' + type + ' will permanently be deleted. Are you sure you want to proceed?'; modal.message = 'This ' + type + ' will permanently be deleted. Are you sure you want to proceed?';

View File

@ -9,13 +9,13 @@ import {TopicComponent} from "./topic.component";
import {TopicRoutingModule} from "./topic-routing.module"; import {TopicRoutingModule} from "./topic-routing.module";
import {ModalModule} from "../openaireLibrary/utils/modal/modal.module"; import {ModalModule} from "../openaireLibrary/utils/modal/modal.module";
import {RouterModule} from "@angular/router"; import {RouterModule} from "@angular/router";
import {FormsModule} from "@angular/forms"; import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {IndicatorsComponent} from "./indicators.component"; import {IndicatorsComponent} from "./indicators.component";
import {AlertModalModule} from "../openaireLibrary/utils/modal/alertModal.module"; import {AlertModalModule} from "../openaireLibrary/utils/modal/alertModal.module";
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, TopicRoutingModule, ModalModule, RouterModule, FormsModule, AlertModalModule CommonModule, TopicRoutingModule, ModalModule, RouterModule, FormsModule, AlertModalModule, ReactiveFormsModule
], ],
declarations: [ declarations: [
TopicComponent, IndicatorsComponent TopicComponent, IndicatorsComponent

View File

@ -269,13 +269,16 @@ export class Stakeholder {
} }
export class Topic { export class Topic {
id:string;
name: string; name: string;
alias: string; alias: string;
description: string; description: string;
isActive: boolean; isActive: boolean;
isPublic: boolean; isPublic: boolean;
isDefault: boolean;
categories: Category[]; categories: Category[];
constructor(name: string, description: string, alias:string , isActive: boolean, isPublic: boolean){ constructor(name: string, description: string, alias:string , isActive: boolean, isPublic: boolean) {
this.id = null;
this.name = name; this.name = name;
this.description = description; this.description = description;
this.alias = alias; this.alias = alias;
@ -285,14 +288,17 @@ export class Topic {
} }
} }
export class Category { export class Category {
id:string;
name: string; name: string;
alias: string; alias: string;
description: string; description: string;
isActive: boolean; isActive: boolean;
isPublic: boolean; isPublic: boolean;
isOverview: boolean; isOverview: boolean;
isDefault: boolean;
subCategories: SubCategory[]; subCategories: SubCategory[];
constructor(name: string, description: string, alias:string , isActive: boolean, isPublic: boolean){ constructor(name: string, description: string, alias:string , isActive: boolean, isPublic: boolean) {
this.id = null;
this.name = name; this.name = name;
this.description = description; this.description = description;
this.alias = alias; this.alias = alias;
@ -303,14 +309,17 @@ export class Category {
} }
export class SubCategory { export class SubCategory {
id:string;
name: string; name: string;
alias: string; alias: string;
description: string; description: string;
isActive: boolean; isActive: boolean;
isPublic: boolean; isPublic: boolean;
isDefault: boolean;
charts: Indicator[]; charts: Indicator[];
numbers: Indicator[]; numbers: Indicator[];
constructor(name: string, description: string, alias:string , isActive: boolean, isPublic: boolean){ constructor(name: string, description: string, alias:string , isActive: boolean, isPublic: boolean) {
this.id = null;
this.name = name; this.name = name;
this.description = description; this.description = description;
this.alias = alias; this.alias = alias;
@ -330,8 +339,10 @@ export class Indicator {
tags:string[]; tags:string[];
isActive: boolean; isActive: boolean;
isPublic: boolean; isPublic: boolean;
isDefault: boolean;
indicatorPaths:IndicatorPath[]; indicatorPaths:IndicatorPath[];
constructor(name: string, description: string, type:string , width:string, isActive: boolean, isPublic: boolean, indicatorPaths:IndicatorPath[]){ constructor(name: string, description: string, type:string , width:string, isActive: boolean, isPublic: boolean, indicatorPaths:IndicatorPath[]){
this.id = null;
this.name = name; this.name = name;
this.description = description; this.description = description;
this.type = type; this.type = type;

View File

@ -1,4 +1,4 @@
import {ChartHelper, Indicator, IndicatorPath} from "./entities/stakeholder"; import {ChartHelper, IndicatorPath} from "./entities/stakeholder";
export class IndicatorUtils { export class IndicatorUtils {
@ -18,9 +18,9 @@ export class IndicatorUtils {
isActiveIcon: string = 'brightness_1'; isActiveIcon: string = 'brightness_1';
public getFullUrl(indicatorPath: IndicatorPath):string{ public getFullUrl(indicatorPath: IndicatorPath): string {
let replacedUrl = indicatorPath.chartObject; let replacedUrl = indicatorPath.chartObject;
if(indicatorPath.parameters) { if (indicatorPath.parameters) {
Object.entries(indicatorPath.parameters).forEach((key, value) => { Object.entries(indicatorPath.parameters).forEach((key, value) => {
replacedUrl = replacedUrl.replace(ChartHelper.prefix + key + ChartHelper.suffix, value.toString()); replacedUrl = replacedUrl.replace(ChartHelper.prefix + key + ChartHelper.suffix, value.toString());
}); });
@ -28,57 +28,58 @@ export class IndicatorUtils {
return indicatorPath.url + encodeURIComponent(replacedUrl); return indicatorPath.url + encodeURIComponent(replacedUrl);
} }
generateIndicatorByChartUrl(url:string): Indicator{ generateIndicatorByChartUrl(source: string, url: string, type: string = null): IndicatorPath {
let indicator = new Indicator("","","chart","small",true,true,[]); let indicatorPath = new IndicatorPath("", source, "", "", []);
let indicatorPath = new IndicatorPath("","","","",[]); if (source === 'stats-tool') {
indicator.indicatorPaths.push(indicatorPath); indicatorPath.url = url.split("json=")[0] + "json=";
if(url.indexOf("json=")!=-1){ indicatorPath.url = indicatorPath.url.split("/")[indicatorPath.url.split("/").length - 1];
indicatorPath.url = url.split("json=")[0]+"json=";
indicatorPath.url = indicatorPath.url.split("/")[indicatorPath.url.split("/").length-1];
indicatorPath.chartObject = decodeURIComponent(url.split("json=")[1]); indicatorPath.chartObject = decodeURIComponent(url.split("json=")[1]);
indicatorPath.source = "stats-tool";
let chart = JSON.parse(indicatorPath.chartObject); let chart = JSON.parse(indicatorPath.chartObject);
indicatorPath.type = this.extractType(chart, indicatorPath); indicatorPath.type = this.extractType(chart, indicatorPath);
this.extractTitle(chart,indicatorPath); this.extractTitle(chart, indicatorPath);
this.extractXTitle(chart,indicatorPath); this.extractXTitle(chart, indicatorPath);
this.extractYTitle(chart,indicatorPath); this.extractYTitle(chart, indicatorPath);
this.extractFunder(chart,indicatorPath); this.extractFunder(chart, indicatorPath);
this.extractStartYear(chart,indicatorPath); this.extractStartYear(chart, indicatorPath);
this.extractEndYear(chart,indicatorPath); this.extractEndYear(chart, indicatorPath);
indicatorPath.chartObject = JSON.stringify(chart); indicatorPath.chartObject = JSON.stringify(chart);
}else if(url.indexOf("data=")!=-1){ } else if (source === 'old') {
indicatorPath.url = url.split("data=")[0]+"data="; indicatorPath.url = url.split("data=")[0] + "data=";
indicatorPath.chartObject = decodeURIComponent(url.split("data=")[1]); indicatorPath.chartObject = decodeURIComponent(url.split("data=")[1]);
indicatorPath.source = "old"; } else {
indicatorPath.url = url;
indicatorPath.type = type;
} }
return indicator; return indicatorPath;
} }
private extractType(obj,indicatorPath:IndicatorPath ):string{ private extractType(obj, indicatorPath: IndicatorPath): string {
let defaultTypes = ["column","bar","pie"]; let defaultTypes = ["column", "bar", "pie"];
let type= obj["chartDescription"]["queries"][0]["type"]; let type = obj["chartDescription"]["queries"][0]["type"];
if(defaultTypes.indexOf(type)==-1){ if (defaultTypes.indexOf(type) == -1) {
type = defaultTypes [0]; type = defaultTypes [0];
}else{ } else {
obj["chartDescription"]["queries"][0]["type"] = ChartHelper.prefix+"type"+ChartHelper.suffix; obj["chartDescription"]["queries"][0]["type"] = ChartHelper.prefix + "type" + ChartHelper.suffix;
indicatorPath.parameters.set("type",type); indicatorPath.parameters.set("type", type);
} }
return type; return type;
} }
private extractFunder(obj,indicatorPath:IndicatorPath ){
private extractFunder(obj, indicatorPath: IndicatorPath) {
let funderName; let funderName;
for(let filter of obj["chartDescription"]["queries"][0]["query"]["filters"]){ for (let filter of obj["chartDescription"]["queries"][0]["query"]["filters"]) {
if(filter["groupFilters"][0]["field"].indexOf(".funder")!=-1){ if (filter["groupFilters"][0]["field"].indexOf(".funder") != -1) {
funderName= filter["groupFilters"][0]["values"][0]; funderName = filter["groupFilters"][0]["values"][0];
filter["groupFilters"][0]["values"][0] = ChartHelper.prefix+"funder_name"+ChartHelper.suffix; filter["groupFilters"][0]["values"][0] = ChartHelper.prefix + "funder_name" + ChartHelper.suffix;
indicatorPath.parameters.set("funder_name",funderName); indicatorPath.parameters.set("funder_name", funderName);
} }
} }
} }
private extractStartYear(obj,indicatorPath:IndicatorPath ){
private extractStartYear(obj, indicatorPath: IndicatorPath) {
let start_year; let start_year;
for(let filter of obj["chartDescription"]["queries"][0]["query"]["filters"]){ for (let filter of obj["chartDescription"]["queries"][0]["query"]["filters"]) {
for(let gfilter of filter["groupFilters"]) { for (let gfilter of filter["groupFilters"]) {
if (gfilter["field"].indexOf(".year") != -1 && gfilter["type"].indexOf(">") != -1) { if (gfilter["field"].indexOf(".year") != -1 && gfilter["type"].indexOf(">") != -1) {
start_year = gfilter["values"][0]; start_year = gfilter["values"][0];
gfilter["values"][0] = ChartHelper.prefix + "start_year" + ChartHelper.suffix; gfilter["values"][0] = ChartHelper.prefix + "start_year" + ChartHelper.suffix;
@ -87,10 +88,11 @@ export class IndicatorUtils {
} }
} }
} }
private extractEndYear(obj,indicatorPath:IndicatorPath ){
private extractEndYear(obj, indicatorPath: IndicatorPath) {
let end_year; let end_year;
for(let filter of obj["chartDescription"]["queries"][0]["query"]["filters"]){ for (let filter of obj["chartDescription"]["queries"][0]["query"]["filters"]) {
for(let gfilter of filter["groupFilters"]) { for (let gfilter of filter["groupFilters"]) {
if (gfilter["field"].indexOf(".year") != -1 && gfilter["type"].indexOf("<") != -1) { if (gfilter["field"].indexOf(".year") != -1 && gfilter["type"].indexOf("<") != -1) {
end_year = gfilter["values"][0]; end_year = gfilter["values"][0];
gfilter["values"][0] = ChartHelper.prefix + "end_year" + ChartHelper.suffix; gfilter["values"][0] = ChartHelper.prefix + "end_year" + ChartHelper.suffix;
@ -99,26 +101,29 @@ export class IndicatorUtils {
} }
} }
} }
private extractTitle(obj,indicatorPath:IndicatorPath ){
let title= obj["chartDescription"]["title"]["text"]; private extractTitle(obj, indicatorPath: IndicatorPath) {
if(obj["chartDescription"]["title"]){ let title = obj["chartDescription"]["title"]["text"];
obj["chartDescription"]["title"]["text"] = ChartHelper.prefix+"title"+ChartHelper.suffix; if (obj["chartDescription"]["title"]) {
indicatorPath.parameters.set("title",title); obj["chartDescription"]["title"]["text"] = ChartHelper.prefix + "title" + ChartHelper.suffix;
indicatorPath.parameters.set("title", title);
} }
} }
private extractXTitle(obj,indicatorPath:IndicatorPath ){
let title= obj["chartDescription"]["xAxis"]["title"]["text"]; private extractXTitle(obj, indicatorPath: IndicatorPath) {
if(obj["chartDescription"]["xAxis"]["title"]){ let title = obj["chartDescription"]["xAxis"]["title"]["text"];
obj["chartDescription"]["xAxis"]["title"]["text"] = ChartHelper.prefix+"xAxisTitle"+ChartHelper.suffix; if (obj["chartDescription"]["xAxis"]["title"]) {
indicatorPath.parameters.set("xAxisTitle",title); obj["chartDescription"]["xAxis"]["title"]["text"] = ChartHelper.prefix + "xAxisTitle" + ChartHelper.suffix;
indicatorPath.parameters.set("xAxisTitle", title);
} }
} }
private extractYTitle(obj,indicatorPath:IndicatorPath ){
let title= obj["chartDescription"]["yAxis"]["title"]["text"]; private extractYTitle(obj, indicatorPath: IndicatorPath) {
if(obj["chartDescription"]["yAxis"]["title"]){ let title = obj["chartDescription"]["yAxis"]["title"]["text"];
obj["chartDescription"]["yAxis"]["title"]["text"] = ChartHelper.prefix+"yAxisTitle"+ChartHelper.suffix; if (obj["chartDescription"]["yAxis"]["title"]) {
indicatorPath.parameters.set("yAxisTitle",title); obj["chartDescription"]["yAxis"]["title"]["text"] = ChartHelper.prefix + "yAxisTitle" + ChartHelper.suffix;
indicatorPath.parameters.set("yAxisTitle", title);
} }
} }

View File

@ -4,7 +4,9 @@ import {EnvironmentSpecificService} from "../../openaireLibrary/utils/properties
import {Observable} from "rxjs"; import {Observable} from "rxjs";
@Injectable() @Injectable({
providedIn: 'root'
})
export class StatisticsService { export class StatisticsService {
numberSources: Map<string, string> = new Map<string, string>(); numberSources: Map<string, string> = new Map<string, string>();
@ -29,4 +31,14 @@ export class StatisticsService {
getChartUrl(source: string, url: string): string { getChartUrl(source: string, url: string): string {
return this.chartSources.get(source) + url; return this.chartSources.get(source) + url;
} }
getChartSource(url: string): string {
let source = 'fake';
this.chartSources.forEach((value, key) => {
if(value !== '' && url.indexOf(value) !== -1) {
source = key;
}
});
return source;
}
} }

View File

@ -20,4 +20,5 @@
--sidebar-width: 320px; --sidebar-width: 320px;
--sidebar-font-size: 16px; --sidebar-font-size: 16px;
--header-height: 70px; --header-height: 70px;
--list-card-max-width: 1220px;
} }

View File

@ -5,6 +5,8 @@
--sidebar-font-size: 16px; --sidebar-font-size: 16px;
--header-height: 70px; --header-height: 70px;
--list-card-max-width: 1220px;
*/ */
/* Global css*/ /* Global css*/
@ -13,12 +15,16 @@ html .dashboard {
color: black; color: black;
} }
.dashboard .clickable {
cursor: pointer;
}
/* On link hover, his items with this class will be displayed*/ /* On link hover, his items with this class will be displayed*/
.dashboard li>a .onHover { .dashboard li > a .onHover {
display: none; display: none;
} }
.dashboard li>a:hover .onHover { .dashboard li > a:hover .onHover {
display: block; display: block;
} }
@ -29,13 +35,13 @@ html .dashboard {
.dashboard #sidebar_main { .dashboard #sidebar_main {
width: var(--sidebar-width); width: var(--sidebar-width);
-webkit-transform: translate3d(calc(-1 * var(--sidebar-width)),0,0); -webkit-transform: translate3d(calc(-1 * var(--sidebar-width)), 0, 0);
transform: translate3d(calc(-1 * var(--sidebar-width)),0,0); transform: translate3d(calc(-1 * var(--sidebar-width)), 0, 0);
} }
.dashboard .sidebar_main_active #sidebar_main { .dashboard .sidebar_main_active #sidebar_main {
-webkit-transform: translate3d(0,0,0); -webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0,0,0); transform: translate3d(0, 0, 0);
} }
.dashboard #sidebar_main .sidebar_main_header { .dashboard #sidebar_main .sidebar_main_header {
@ -75,7 +81,7 @@ body.dashboard {
} }
.dashboard #header_main { .dashboard #header_main {
padding: calc((var(--header-height) - 48px)/2) 25px; padding: calc((var(--header-height) - 48px) / 2) 25px;
} }
/* Custom card*/ /* Custom card*/
@ -87,8 +93,19 @@ body.dashboard {
color: rgba(0, 0, 0, 0.8); color: rgba(0, 0, 0, 0.8);
} }
@media only screen and (max-width: 767px) {
.dashboard .md-card .md-card-toolbar .md-card-toolbar-actions span {
display: none;
}
}
.dashboard .md-card .md-card-toolbar .md-card-toolbar-heading-text { .dashboard .md-card .md-card-toolbar .md-card-toolbar-heading-text {
font-weight: 700; font-weight: 700;
float: none;
}
.dashboard .list .md-card {
max-width: var(--list-card-max-width);
} }
/* Breadcrumb*/ /* Breadcrumb*/
@ -112,9 +129,20 @@ body.dashboard {
/* Notification */ /* Notification */
/* Remove the second close added by theme because it was used uikit 2*/ /* Remove the second close added by theme because it was used uikit 2*/
.dashboard .uk-close::after {content: '';} .dashboard .uk-close::after {
content: '';
}
/* Change z-index, because of sidebar and header z-index is bigger that default */ /* Change z-index, because of sidebar and header z-index is bigger that default */
.dashboard .uk-notification { .dashboard .uk-notification {
z-index: 2000; z-index: 2000;
} }
/* Form */
.dashboard .uk-form-stacked .uk-form-label {
font-size: 14px;
font-weight: 700;
padding: 0;
margin-top: 5px;
}