[Monitor Dashboard | Trunk]

Indicators Page: 
 - keep parameters 
 - add feadback link

Admin manage number indicators:

 - add message when stakeholder parameterization is not applied
 - preview the number API url (similar to charts)
 - json path: auto generate if the first one has comma separated values
 - fix stakeholder parameterization for numbers from stats-tool

Filtering:
 - fixes


git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-monitor-portal/trunk/monitor_dashboard@59224 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
Argiro Kokogiannaki 2020-08-06 07:34:41 +00:00
parent 9c93f0760a
commit 7d57db25e0
11 changed files with 95 additions and 30 deletions

View File

@ -23,7 +23,8 @@
"generate:prerender": "cd dist && node prerender", "generate:prerender": "cd dist && node prerender",
"webpack:server": "webpack --config webpack.server.config.js --progress --colors", "webpack:server": "webpack --config webpack.server.config.js --progress --colors",
"serve:prerender": "cd dist/browser && http-server", "serve:prerender": "cd dist/browser && http-server",
"serve:ssr": "node dist/server" "serve:ssr": "node dist/server",
"after-build-clean": "rm -rf src node_modules .idea/ installOpenaireLib.sh deploy dist/browser/assets/common-assets/.svn/ dist/browser/stats.json ; "
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {

View File

@ -50,7 +50,7 @@
[activeItem]="activeTopic?activeTopic.alias:null" [showHeader]=true [activeItem]="activeTopic?activeTopic.alias:null" [showHeader]=true
[searchLink]="(properties.showContent)?properties.searchLinkToResults:null" [searchLink]="(properties.showContent)?properties.searchLinkToResults:null"
[searchParams]="createSearchParameters()" [searchParams]="createSearchParameters()"
[headerUrl]="properties.baseLink" [headerUrl]="properties.baseLink" queryParamsHandling="preserve"
></dashboard-sidebar> ></dashboard-sidebar>
<dashboard-sidebar *ngIf="hasAdminMenu" [items]="adminMenuItems" headerName="Monitor" <dashboard-sidebar *ngIf="hasAdminMenu" [items]="adminMenuItems" headerName="Monitor"
headerDashboard="Administration Panel" [headerUrl]="properties.baseLink" headerDashboard="Administration Panel" [headerUrl]="properties.baseLink"

View File

@ -94,6 +94,7 @@
<div class="uk-text-large "></div> <div class="uk-text-large "></div>
</div> </div>
</div> </div>
<div *ngIf="!privateStakeholder">
<div <div
*ngIf="(activeSubCategory && (activeSubCategory.charts.length == 0 || *ngIf="(activeSubCategory && (activeSubCategory.charts.length == 0 ||
(activeSubCategory.charts.length == 1 && activeSubCategory.charts[0].indicators.length == 0))) (activeSubCategory.charts.length == 1 && activeSubCategory.charts[0].indicators.length == 0)))
@ -136,8 +137,10 @@
[class.uk-disabled]="indicator.indicatorPaths[0].filtersApplied < countSelectedFilters()" [class.uk-disabled]="indicator.indicatorPaths[0].filtersApplied < countSelectedFilters()"
[class.semiFiltered]="indicator.indicatorPaths[0].filtersApplied < countSelectedFilters()"> [class.semiFiltered]="indicator.indicatorPaths[0].filtersApplied < countSelectedFilters()">
<div class="md-card-content uk-text-center"> <div class="md-card-content uk-text-center">
<!--<div>Filtered: {{indicator.indicatorPaths[0].filtersApplied}} out of <div *ngIf="properties.environment == 'development'">Filtered:
{{countSelectedFilters()}}</div>--> {{indicator.indicatorPaths[0].filtersApplied}}
out of
{{countSelectedFilters()}}</div>
<div class="uk-text-bold ">{{indicator.name}}</div> <div class="uk-text-bold ">{{indicator.name}}</div>
<h3 *ngIf="numberResults.get(i + '-' + j)" class="uk-margin-medium-top uk-text-bold"> <h3 *ngIf="numberResults.get(i + '-' + j)" class="uk-margin-medium-top uk-text-bold">
<span>{{numberResults.get(i + '-' + j) | number}}</span> <span>{{numberResults.get(i + '-' + j) | number}}</span>
@ -181,8 +184,8 @@
{{indicatorPath.type}} {{indicatorPath.type}}
</button> </button>
</div> </div>
<!--<div>Filtered: {{chartsActiveType.get(i + '-' + j).filtersApplied}} out of <div *ngIf="properties.environment == 'development'">Filtered: {{chartsActiveType.get(i + '-' + j).filtersApplied}} out of
{{countSelectedFilters()}}</div>--> {{countSelectedFilters()}}</div>
<iframe *ngIf="chartsActiveType.get(i + '-' + j).source !== 'image'" <iframe *ngIf="chartsActiveType.get(i + '-' + j).source !== 'image'"
[src]="chartsActiveType.get(i + '-' + j).safeResourceUrl" [src]="chartsActiveType.get(i + '-' + j).safeResourceUrl"
class="uk-width-1-1 uk-height-medium"></iframe> class="uk-width-1-1 uk-height-medium"></iframe>
@ -199,6 +202,12 @@
</ng-template> </ng-template>
</div> </div>
</div> </div>
<div *ngIf="!loading && !privateStakeholder && activeSubCategory"
class="uk-width-1-1 uk-text-center uk-text-muted">
<span>Send us your <a [href]="mailText" target="_self" (click)="mailMe()">feedback</a>.</span>
</div>
</div>
</div> </div>
</div> </div>
<div *ngIf="stakeholder" class="uk-margin-xlarge-top"> <div *ngIf="stakeholder" class="uk-margin-xlarge-top">

View File

@ -200,7 +200,8 @@ export class MonitorComponent implements OnInit, OnDestroy {
}else{ }else{
delete this.queryParams["year"]; delete this.queryParams["year"];
} }
this.location.go(location.pathname, this.routerHelper.createQueryParamsString( Object.keys(this.queryParams), Object.values(this.queryParams))); // this.location.go(location.pathname, this.routerHelper.createQueryParamsString( Object.keys(this.queryParams), Object.values(this.queryParams)));
this.router.navigate([], {queryParams: this.queryParams });
this.setIndicators(); this.setIndicators();
} }
} }
@ -329,7 +330,7 @@ export class MonitorComponent implements OnInit, OnDestroy {
delete this.queryParams[$event.value.filterId]; delete this.queryParams[$event.value.filterId];
} }
if(navigate) { if(navigate) {
this.location.go(location.pathname, this.routerHelper.createQueryParamsString( Object.keys(this.queryParams), Object.values(this.queryParams))); this.router.navigate([], {queryParams: this.queryParams });
this.setIndicators(); this.setIndicators();
} }
@ -416,7 +417,7 @@ export class MonitorComponent implements OnInit, OnDestroy {
public navigateTo(stakeholder: string, topic: string, category: string = null, subcategory: string = null) { public navigateTo(stakeholder: string, topic: string, category: string = null, subcategory: string = null) {
let url = stakeholder + '/' + topic + ((category) ? ('/' let url = stakeholder + '/' + topic + ((category) ? ('/'
+ category) : '') + ((subcategory) ? ('/' + subcategory) : ''); + category) : '') + ((subcategory) ? ('/' + subcategory) : '');
return this._router.navigate([url]); return this._router.navigate([url],{ queryParams: this.queryParams});
} }
public quote(param: string): string { public quote(param: string): string {
@ -460,4 +461,13 @@ export class MonitorComponent implements OnInit, OnDestroy {
} }
return counter; return counter;
} }
/*
Feedback mail
*/
public get mailText() {
return "mailto:"+this.properties.feedbackmail+"?subject=%5BOpenAIRE%20Monitor%5D%20"+(this.stakeholder?this.stakeholder.name:"")+"%20dashboard%20feedback"
}
mailMe(){
window.location.href = this.mailText;
}
} }

View File

@ -430,11 +430,14 @@
<div dashboard-input [formInput]="indicatorPath.get('url')" type="textarea" rows="3" <div dashboard-input [formInput]="indicatorPath.get('url')" type="textarea" rows="3"
label="Number path url"></div> label="Number path url"></div>
</div> </div>
<!--<div class="uk-width-1-3@s"> <div *ngIf="urlParameterizedMessage.length > 0" class="uk-alert-warning uk-alert">
{{urlParameterizedMessage}}
</div>
<div class="uk-width-1-3@s">
<div dashboard-input [formInput]="indicatorPath.get('source')" label="Source" <div dashboard-input [formInput]="indicatorPath.get('source')" label="Source"
type="select" [options]="indicatorUtils.sourceTypes"> type="select" [options]="indicatorUtils.sourceTypes">
</div> </div>
</div>--> </div>
</div> </div>
<div formArrayName="jsonPath"> <div formArrayName="jsonPath">
<div class="uk-margin-top uk-margin-bottom uk-text-large"> <div class="uk-margin-top uk-margin-bottom uk-text-large">

View File

@ -391,6 +391,17 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
} }
public addJsonPath(index: number) { public addJsonPath(index: number) {
if(index==0 && this.getJsonPath(index).getRawValue()[index].indexOf(",")!=-1){
//if in the first path there are more than one paaths comma separated, split them and autogenerate the forms
let paths = this.getJsonPath(index).getRawValue()[index].split(",");
for(let i = 0; i< paths.length; i++){
if(i !=0){
this.getJsonPath(index).push(this.fb.control('', Validators.required));
}
}
this.getJsonPath(index).setValue(paths)
return;
}
this.getJsonPath(index).push(this.fb.control('', Validators.required)); this.getJsonPath(index).push(this.fb.control('', Validators.required));
} }
@ -435,20 +446,44 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.subscriptions.push(this.numberIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => { this.subscriptions.push(this.numberIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => {
if (this.numberIndicatorPaths.at(index).get('url').valid) { if (this.numberIndicatorPaths.at(index).get('url').valid) {
let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.statisticsService.getNumberSource(value), value, this.stakeholder,this.numberIndicatorPaths.at(index).get('jsonPath').value ); let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.statisticsService.getNumberSource(value), value, this.stakeholder,this.numberIndicatorPaths.at(index).get('jsonPath').value );
// if(indicatorPath.url.indexOf("index_id") ==-1 && indicatorPath.url.indexOf("index_name") ==-1 && (indicatorPath.url).indexOf("index_shortName") ==-1 ){ if((indicatorPath.chartObject && Object.keys(indicatorPath.parameters).indexOf("index_id") ==-1 && Object.keys(indicatorPath.parameters).indexOf("index_name") ==-1 && Object.keys(indicatorPath.parameters).indexOf("index_shortName") ==-1 )
// || (!indicatorPath.chartObject && indicatorPath.url.indexOf("index_id") ==-1 && indicatorPath.url.indexOf("index_name") ==-1 && (indicatorPath.url).indexOf("index_shortName") ==-1 )){
// }else { // default profile
// this.urlParameterizedMessage = ""; if(this.stakeholder.defaultId == null){
// } this.urlParameterizedMessage = "This indicator couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly."
}else{
this.urlParameterizedMessage = "This indicator couldn't be generated properly. Please make sure chart data is for the current stakeholder."
}
}else {
this.urlParameterizedMessage = "";
}
/* if(value != indicatorPath.url) { /* if(value != indicatorPath.url) {
(this.numberIndicatorPaths.at(index) as FormGroup).get('url').setValue( indicatorPath.url); (this.numberIndicatorPaths.at(index) as FormGroup).get('url').setValue( indicatorPath.url);
}*/ }*/
if (!this.indicator.indicatorPaths[index]) { if (!this.indicator.indicatorPaths[index]) {
this.indicator.indicatorPaths[index] = indicatorPath; this.indicator.indicatorPaths[index] = indicatorPath;
} else { } else {
this.indicator.indicatorPaths[index] = indicatorPath; this.indicator.indicatorPaths[index] = indicatorPath;
} }
(this.numberIndicatorPaths.at(index) as FormGroup).get('source').setValue(indicatorPath.source);
}
})
);
this.subscriptions.push(this.numberIndicatorPaths.at(index).get('jsonPath').valueChanges.subscribe(value => {
if (!this.indicator.indicatorPaths[index]) {
this.indicator.indicatorPaths[index].jsonPath = value;
} else {
this.indicator.indicatorPaths[index].jsonPath = value;
}
})
);
this.subscriptions.push(this.numberIndicatorPaths.at(index).get('source').valueChanges.subscribe(value => {
if (!this.indicator.indicatorPaths[index]) {
this.indicator.indicatorPaths[index].source = value;
} else {
this.indicator.indicatorPaths[index].source = value;
} }
}) })
); );
@ -534,6 +569,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
} }
public editNumberIndicatorOpen(section: Section, id = null) { public editNumberIndicatorOpen(section: Section, id = null) {
this.urlParameterizedMessage = "";
this.section = section; this.section = section;
this.index = (id) ? section.indicators.findIndex(value => value._id === id) : -1; this.index = (id) ? section.indicators.findIndex(value => value._id === id) : -1;
if (this.index !== -1) { if (this.index !== -1) {
@ -550,7 +586,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
defaultId: this.fb.control(this.indicator.defaultId) defaultId: this.fb.control(this.indicator.defaultId)
}); });
this.indicator.indicatorPaths.forEach(indicatorPath => { this.indicator.indicatorPaths.forEach(indicatorPath => {
this.addNumberIndicatorPath(indicatorPath.url,indicatorPath.parameters, indicatorPath.source, this.getJsonPathAsFormArray(indicatorPath)); this.addNumberIndicatorPath(this.statisticsService.getNumberUrl(indicatorPath.source,this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)),indicatorPath.parameters, indicatorPath.source, this.getJsonPathAsFormArray(indicatorPath));
}); });
} else { } else {
this.indicator = new Indicator('', '', 'number', 'small', true, true, []); this.indicator = new Indicator('', '', 'number', 'small', true, true, []);

View File

@ -224,7 +224,7 @@ export class IndicatorUtils {
]); ]);
public getFullUrl(stakeholder:Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null): string { public getFullUrl(stakeholder:Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null): string {
let replacedUrl = indicatorPath.chartObject; let replacedUrl =indicatorPath.chartObject?indicatorPath.chartObject:indicatorPath.url;
if (indicatorPath.parameters) { if (indicatorPath.parameters) {
Object.keys(indicatorPath.parameters).forEach(key => { Object.keys(indicatorPath.parameters).forEach(key => {
let replacedValue = indicatorPath.parameters[key]; let replacedValue = indicatorPath.parameters[key];
@ -294,7 +294,7 @@ export class IndicatorUtils {
if(indicatorPath.url.indexOf(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix) !=- 1){ if(indicatorPath.url.indexOf(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix) !=- 1){
indicatorPath.url = replacedUrl.split(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_shortName)) indicatorPath.url = replacedUrl.split(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_shortName))
} }
return indicatorPath.url + encodeURIComponent(replacedUrl); return (indicatorPath.chartObject?indicatorPath.url + encodeURIComponent(replacedUrl):replacedUrl);
} }
public getFullUrlWithFilters(stakeholder:Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null, coFunded:boolean=false): string { public getFullUrlWithFilters(stakeholder:Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null, coFunded:boolean=false): string {
indicatorPath.filtersApplied = 0; indicatorPath.filtersApplied = 0;
@ -400,6 +400,9 @@ export class IndicatorUtils {
filterApplied = true; filterApplied = true;
} }
} else { } else {
if((paramFields.length*2) == queries["query"]["parameters"].length){
queries["query"]["parameters"].splice(paramFields.length, 0, filterValue);
}
if((paramFields.length*2 + 4) == queries["query"]["parameters"].length){ if((paramFields.length*2 + 4) == queries["query"]["parameters"].length){
queries["query"]["parameters"].splice(paramFields.length + 1, 0, filterValue); queries["query"]["parameters"].splice(paramFields.length + 1, 0, filterValue);
} }
@ -439,7 +442,7 @@ export class IndicatorUtils {
queries["query"]["filters"] = []; queries["query"]["filters"] = [];
} }
let field = queries["query"]["select"][0]["field"]; let field = queries["query"]["select"][0]["field"];
let filterString = IndicatorFilterUtils.getFilter(field,filterType); let filterString = IndicatorFilterUtils.getFilter(field&&field.length > 0? field.split(".")[0]:"",filterType);
if(filterString){ if(filterString){
let filter = JSON.parse(filterString); let filter = JSON.parse(filterString);
let filterposition = IndicatorFilterUtils.filterIndexOf(filter,queries["query"]["filters"]) let filterposition = IndicatorFilterUtils.filterIndexOf(filter,queries["query"]["filters"])
@ -484,10 +487,11 @@ export class IndicatorUtils {
let filterposition = IndicatorFilterUtils.filterIndexOf(filter, queries["query"]["filters"]); let filterposition = IndicatorFilterUtils.filterIndexOf(filter, queries["query"]["filters"]);
if (filterposition) { if (filterposition) {
if (values.indexOf(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0]) == -1) { if (values.indexOf(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0]) == -1) {
values.push(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0]) values.push(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0]);
} }
} }
} }
console.debug(values);
return values.length > 1; return values.length > 1;
} }
generateIndicatorByForm(form: any, indicatorPaths: IndicatorPath[], type:IndicatorType, addParameters:boolean = true ): Indicator { generateIndicatorByForm(form: any, indicatorPaths: IndicatorPath[], type:IndicatorType, addParameters:boolean = true ): Indicator {
@ -515,6 +519,7 @@ export class IndicatorUtils {
indicatorPath.chartObject = decodeURIComponent(url.indexOf("json=")!=-1?url.split("json=")[1]:""); indicatorPath.chartObject = decodeURIComponent(url.indexOf("json=")!=-1?url.split("json=")[1]:"");
let chart = JSON.parse(indicatorPath.chartObject); let chart = JSON.parse(indicatorPath.chartObject);
this.extractStakeHolders(chart, indicatorPath, stakeholder); this.extractStakeHolders(chart, indicatorPath, stakeholder);
indicatorPath.chartObject = JSON.stringify(chart);
// this.addResultFilters(chart, indicatorPath); // this.addResultFilters(chart, indicatorPath);
}else { }else {
try { try {
@ -649,7 +654,7 @@ export class IndicatorUtils {
if(stakeholder.type != "ri"){ if(stakeholder.type != "ri"){
return; return;
} }
for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) { for (let query of this.getQueryObjectName(obj)?obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]:obj[this.getDescriptionObjectName(obj)]) {
if (!query["query"]["filters"]) { if (!query["query"]["filters"]) {
return; return;
} }
@ -671,7 +676,7 @@ export class IndicatorUtils {
if(stakeholder.type != "organization"){ if(stakeholder.type != "organization"){
return; return;
} }
for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) { for (let query of this.getQueryObjectName(obj)?obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]:obj[this.getDescriptionObjectName(obj)]) {
if (!query["query"]["filters"]) { if (!query["query"]["filters"]) {
return; return;
} }

View File

@ -42,6 +42,9 @@ export class StatisticsService {
getChartUrl(source: SourceType, url: string): string { getChartUrl(source: SourceType, url: string): string {
return this.chartSources.get(source)[0] + url; return this.chartSources.get(source)[0] + url;
} }
getNumberUrl(source: string, url: string): string {
return this.numberSources.get(this.getSourceType(source))[0] + url;
}
getNumberSource(url: string): SourceType { getNumberSource(url: string): SourceType {
let source: SourceType = 'search'; let source: SourceType = 'search';
this.numberSources.forEach((values, key) => { this.numberSources.forEach((values, key) => {

View File

@ -294,10 +294,7 @@ bottom a:not(.license), bottom a > :not(svg) {
opacity: 0.5; opacity: 0.5;
} }
.stakeholderPage:not(.sidebar_mini) #sidebar_main .menu_section > ul.searchLink { .stakeholderPage:not(.sidebar_mini) #sidebar_main .menu_section > ul.searchLink {
bottom: 120px; margin-top: 80px !important;
right:0;
left:0;
position:fixed;
} }
.stakeholderPage #page_content.greyOut:before { .stakeholderPage #page_content.greyOut:before {

View File

@ -72,6 +72,7 @@ html .dashboard {
.dashboard .sidebar_mini #sidebar_main .sidebar_main_header .portalLogo{ .dashboard .sidebar_mini #sidebar_main .sidebar_main_header .portalLogo{
background: url("/assets/logo-small-monitor.png") no-repeat !important; background: url("/assets/logo-small-monitor.png") no-repeat !important;
background-size: 50px 50px !important;
/* background-size: contain !important; /* background-size: contain !important;
margin-left: 5px;*/ margin-left: 5px;*/

View File

@ -53,7 +53,7 @@ export let properties: EnvProperties = {
cookieDomain: ".openaire.eu", cookieDomain: ".openaire.eu",
feedbackmail: "openaire.test@gmail.com", feedbackmail: "feedback@openaire.eu",
cacheUrl: "https://demo.openaire.eu/cache/get?url=", cacheUrl: "https://demo.openaire.eu/cache/get?url=",