[Monitor Dashboard|Trunk]

Description:
	add additional description field
	add tooltip to  show description
Manage stakeholders: 
	add checks for roles


git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-monitor-portal/trunk/monitor_dashboard@59713 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
Argiro Kokogiannaki 2020-10-29 09:17:39 +00:00
parent f68b7187e9
commit df36b36b5d
11 changed files with 76 additions and 44 deletions

View File

@ -100,8 +100,8 @@ export class AppComponent implements OnInit, OnDestroy {
this.stakeholderService.getStakeholder(this.properties.monitorServiceAPIURL, params['stakeholder']).subscribe(stakeholder => {
if(stakeholder) {
this.stakeholder = stakeholder;
this.buildMenu();
LinksResolver.setProperties(this.stakeholder.alias);
this.buildMenu();
this.stakeholderService.setStakeholder(stakeholder);
this.layoutService.setSmallScreen((this.innerWidth && this.innerWidth < 1219));
this.layoutService.setOpen(!(this.innerWidth && this.innerWidth < 1219));
@ -209,13 +209,13 @@ export class AppComponent implements OnInit, OnDestroy {
position: 'center',
badge: false
};
// if(this.isAdmin()) {
if(this.isAdmin()) {
this.menuItems.push({
rootItem: new MenuItem("manage", "Manage",
"", "/admin", false, [], null, {}), items: []
});
// }
}
this.specialSideBarMenuItem = new MenuItem("search", "Search research outcomes", "", this.properties.searchLinkToResults, false, [], null, {})
this.specialSideBarMenuItem.icon = '<span uk-icon="search"></span>';
@ -282,7 +282,7 @@ export class AppComponent implements OnInit, OnDestroy {
}
public isAdmin() {
return this.user && (Session.isPortalAdministrator(this.user) || Session.isCommunityCurator(this.user) || Session.isMonitorCurator(this.user));
return this.user && (Session.isPortalAdministrator(this.user) || Session.isCommunityCurator(this.user) || Session.isMonitorCurator(this.user) || (this.stakeholder && Session.isManager(this.stakeholder.type,this.stakeholder.alias,this.user)));
}
public isPublicOrIsMember(visibility: Visibility): boolean {

View File

@ -1,9 +1,9 @@
<div id="page_content">
<div id="page_content_inner">
<div>
<div *ngIf="isCurator()">
<ul class="uk-tab customTabs admin" uk-tab>
<li [class.uk-active]="tab === 'managers'"><a (click)="changeTab('all')"><span class="title">All</span></a></li>
<li *ngIf="isAdministrator()" [class.uk-active]="tab === 'members'"><a (click)="changeTab('templates')"><span class="title">Profile templates</span></a></li>
<li [class.uk-active]="tab === 'members'"><a (click)="changeTab('templates')"><span class="title">Profile templates</span></a></li>
<li [class.uk-active]="tab === 'members'"><a (click)="changeTab('profiles')"><span class="title">Profiles</span></a></li>
</ul>
@ -23,7 +23,7 @@
</div>
</div>
</div>
<div *ngIf="tab != 'profiles' && isAdministrator()" class="uk-margin-top">
<div *ngIf="tab != 'profiles' && isCurator()" class="uk-margin-top">
<h6 class="main">Profile Templates</h6>
<div class = "uk-child-width-1-4@m uk-child-width-1-3@s uk-grid-match uk-grid-small"
uk-grid>
@ -31,13 +31,13 @@
<ng-template ngFor [ngForOf]="displayDefaultStakeholders" let-stakeholder let-i="index">
<ng-container *ngTemplateOutlet="stakeholderBox; context: {stakeholder:stakeholder}"></ng-container>
</ng-template>
<div *ngIf="!loading">
<div *ngIf="!loading && isCurator()">
<ng-container *ngTemplateOutlet="newBox; context:
{text:'Create a new default profile.', isDefault:true}"></ng-container>
</div>
</div>
</div>
<div *ngIf="tab != 'templates'" class="uk-margin-top">
<div *ngIf="tab != 'templates' && isManager()" class="uk-margin-top">
<h6 class="">Profiles</h6>
<div class="uk-grid-match uk-grid-small uk-child-width-1-4@m uk-child-width-1-3@s"
uk-grid>
@ -45,7 +45,7 @@
<ng-template ngFor [ngForOf]="displayStakeholders" let-stakeholder let-i="index">
<ng-container *ngTemplateOutlet="stakeholderBox; context: {stakeholder:stakeholder}"></ng-container>
</ng-template>
<div *ngIf="!loading">
<div *ngIf="!loading && isCurator()">
<ng-container *ngTemplateOutlet="newBox; context:
{text:'Create a new profile by selecting the type (Funder, Organization, Research Initiative or Project) and '+
' select indicators based on a default or a blank profile.', isDefault:false}"></ng-container>
@ -73,8 +73,8 @@
{{'Make ' + v.label.toLowerCase()}}</a>
</li>
</ng-template>
<hr *ngIf="isAdministrator()" class="uk-nav-divider">
<li *ngIf="isAdministrator()"><a
<hr *ngIf="isProfileManager(stakeholder)" class="uk-nav-divider">
<li *ngIf="isProfileManager(stakeholder)"><a
(click)="$event.stopPropagation();deleteStakeholderOpen(stakeholder);hide(element);$event.preventDefault()">Delete</a>
</li>
</ul>

View File

@ -232,8 +232,16 @@ export class ManageStakeholdersComponent implements OnInit, OnDestroy {
stakeholder.isPublic = isPublic;
});
}
public isAdministrator(): boolean {
public isManager(): boolean {
return this.isCurator() || (Session.isKindOfMonitorManager(this.user));
}
public isProfileManager(stakeholder:Stakeholder): boolean {
return this.isCurator() || (Session.isManager(stakeholder.type, stakeholder.alias, this.user));
}
public isCurator(): boolean {
return this.isAdmin() || Session.isCommunityCurator(this.user) || Session.isMonitorCurator(this.user);
}
public isAdmin(): boolean {
return Session.isPortalAdministrator(this.user);
}
changeTab(tab:"all" | "templates" | "profiles"){

View File

@ -135,7 +135,7 @@
[class.uk-width-1-3@m]="indicator.width === 'small'"
[class.uk-width-1-2@m]="indicator.width === 'medium'"
[class.uk-width-1-1]="indicator.width === 'large'" class=" uk-margin-bottom">
<div class="uk-card uk-card-default" [attr.uk-tooltip]="indicator.description"
<div class="uk-card uk-card-default"
[class.uk-disabled]="indicator.indicatorPaths[0].filtersApplied < countSelectedFilters()"
[class.semiFiltered]="indicator.indicatorPaths[0].filtersApplied < countSelectedFilters()">
<div class="uk-card-body uk-text-center">
@ -147,7 +147,7 @@
<h3 *ngIf="numberResults.get(i + '-' + j)" class="uk-margin-medium-top uk-text-bold">
<span>{{numberResults.get(i + '-' + j) | number}}</span>
</h3>
<ng-container *ngTemplateOutlet="description; context: {indicator:indicator}"></ng-container>
</div>
</div>
</div>
@ -173,10 +173,7 @@
<div class="uk-card uk-card-default"
[class.uk-disabled]="chartsActiveType.get(i + '-' + j).filtersApplied < countSelectedFilters()"
[class.semiFiltered]="chartsActiveType.get(i + '-' + j).filtersApplied < countSelectedFilters()"
><!--[
attr
.uk-tooltip]="indicator
.description">-->
>
<div class="uk-card-body uk-text-center">
<div *ngIf="indicator.indicatorPaths.length > 1" class="uk-button-group">
<button *ngFor="let indicatorPath of indicator.indicatorPaths;"
@ -196,7 +193,7 @@
<img *ngIf="chartsActiveType.get(i + '-' + j).source === 'image'"
[src]="chartsActiveType.get(i + '-' + j).safeResourceUrl"
class="uk-width-1-1 uk-height-medium">
<div class="uk-text-small uk-text-muted">{{indicator.description}}</div>
<ng-container *ngTemplateOutlet="description; context: {indicator:indicator}"></ng-container>
</div>
</div>
</div>
@ -267,4 +264,14 @@
</div>
</div>
<ng-template #description let-indicator="indicator">
<span class="descriptionIcon"
*ngIf="(indicator.description && indicator.description.length > 0)
|| (indicator.additionalDescription && indicator.additionalDescription.length > 0)"
uk-icon="info"
[attr.uk-tooltip]="'title:<div class=\'uk-padding-small\'>'+
(indicator.description&& indicator.description.length > 0?indicator.description:'') +'<br>'+
(indicator.additionalDescription && indicator.additionalDescription.length?indicator.additionalDescription:'')
+'</div>'">
</span>
</ng-template>

View File

@ -87,7 +87,7 @@
[class.disable-sortable]="!canReorder"
[class.uk-sortable-nodrag]="!canReorder">
<div class="uk-card uk-card-default" [class.md-card-hover]="canReorder">
<div class="uk-padding-small ">
<div class="uk-padding-small uk-padding-remove-bottom ">
<ng-container *ngTemplateOutlet="visibilityOptions; context:{indicator: indicator}"></ng-container>
<div class="md-card-toolbar-actions uk-float-right" >
@ -118,14 +118,17 @@
</div>
</div>
<div class="">
<div class="uk-flex uk-flex-center" uk-grid>
<div class="">
<div class=" uk-padding-small uk-padding-remove-top">
<div class="">
<div class="uk-text-center">
{{indicator.name ? indicator.name : 'No title available'}}
</div>
<div class="uk-width-1-1">
{{indicator.description}}
</div>
<div class="uk-width-1-1">
{{indicator.additionalDescription}}
</div>
</div>
</div>
</div>
@ -250,6 +253,9 @@
<div class="uk-width-1-1 uk-text-muted uk-text-small">
{{indicator.description ? indicator.description : ''}}
</div>
<div class="uk-width-1-1 uk-text-muted uk-text-small">
{{indicator.additionalDescription ? indicator.additionalDescription : ''}}
</div>
</div>
</div>
</div>
@ -290,9 +296,12 @@
[okDisabled]="numberIndicatorFb && (numberIndicatorFb.invalid || numberIndicatorFb.pristine)">
<div *ngIf="numberIndicatorFb" class="uk-padding-small" [formGroup]="numberIndicatorFb">
<div dashboard-input class="uk-form-row" [formInput]="numberIndicatorFb.get('name')" label="Title"></div>
<div dashboard-input class="uk-form-row" [formInput]="numberIndicatorFb.get('description')"
<div *ngIf="isAdministrator" dashboard-input class="uk-form-row" [formInput]="numberIndicatorFb.get('description')"
label="Description" type="textarea">
</div>
<div dashboard-input class="uk-form-row" [formInput]="numberIndicatorFb.get('additionalDescription')"
label="Additional information" type="textarea">
</div>
<div class="uk-form-row uk-flex uk-flex-middle">
<div dashboard-input class="uk-width-small" [formInput]="numberIndicatorFb.get('visibility')"
label="Visibility" [options]="stakeholderUtils.visibility" type="select">
@ -352,9 +361,12 @@
[okDisabled]="chartIndicatorFb && (chartIndicatorFb.invalid || chartIndicatorFb.pristine)">
<div *ngIf="chartIndicatorFb" class="uk-padding-small" [formGroup]="chartIndicatorFb">
<div dashboard-input class="uk-form-row" [formInput]="chartIndicatorFb.get('name')" label="Title"></div>
<div dashboard-input class="uk-form-row" [formInput]="chartIndicatorFb.get('description')"
<div *ngIf="isAdministrator" dashboard-input class="uk-form-row" [formInput]="chartIndicatorFb.get('description')"
label="Description" type="textarea">
</div>
<div dashboard-input class="uk-form-row" [formInput]="chartIndicatorFb.get('additionalDescription')"
label="Additional information" type="textarea">
</div>
<div class="uk-form-row uk-flex uk-flex-middle">
<div dashboard-input class="uk-width-small" [formInput]="chartIndicatorFb.get('visibility')"
label="Visibility" [options]="stakeholderUtils.visibility" type="select">

View File

@ -321,6 +321,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
sections.forEach(section =>
section.indicators = section.indicators.filter(indicator => (indicator.name && indicator.name.toLowerCase().includes(value.toLowerCase()))
|| (indicator.description && indicator.description.toLowerCase().includes(value.toLowerCase()))
|| (indicator.additionalDescription && indicator.additionalDescription.toLowerCase().includes(value.toLowerCase()))
|| indicator.indicatorPaths.filter(indicatorPath => (indicatorPath.parameters && indicatorPath.parameters.title &&
indicatorPath.parameters.title.includes(value.toLowerCase()))).length > 0));
}
@ -567,6 +568,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
_id: this.fb.control(this.indicator._id),
name: this.fb.control(this.indicator.name, Validators.required),
description: this.fb.control(this.indicator.description),
additionalDescription: this.fb.control(this.indicator.additionalDescription),
visibility: this.fb.control(this.indicator.visibility),
indicatorPaths: this.fb.array([], Validators.required),
type: this.fb.control(this.indicator.type),
@ -577,11 +579,12 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.addNumberIndicatorPath(this.statisticsService.getNumberUrl(indicatorPath.source,this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)),indicatorPath.parameters, indicatorPath.source, this.getJsonPathAsFormArray(indicatorPath));
});
} else {
this.indicator = new Indicator('', '', 'number', 'small', "PUBLIC", []);
this.indicator = new Indicator('', '', '','number', 'small', "PUBLIC", []);
this.numberIndicatorFb = this.fb.group({
_id: this.fb.control(this.indicator._id),
name: this.fb.control(this.indicator.name, Validators.required),
description: this.fb.control(this.indicator.description),
additionalDescription: this.fb.control(this.indicator.additionalDescription),
visibility: this.fb.control(this.indicator.visibility),
indicatorPaths: this.fb.array([], Validators.required),
type: this.fb.control(this.indicator.type),
@ -618,6 +621,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
_id: this.fb.control(this.indicator._id),
name: this.fb.control(this.indicator.name),
description: this.fb.control(this.indicator.description),
additionalDescription: this.fb.control(this.indicator.additionalDescription),
visibility: this.fb.control(this.indicator.visibility),
indicatorPaths: this.fb.array([]),
width: this.fb.control(this.indicator.width),
@ -629,11 +633,12 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath);
});
} else {
this.indicator = new Indicator('', '', 'chart', 'medium', "PUBLIC",[]);
this.indicator = new Indicator('', '', '', 'chart', 'medium', "PUBLIC",[]);
this.chartIndicatorFb = this.fb.group({
_id: this.fb.control(this.indicator._id),
name: this.fb.control(this.indicator.name),
description: this.fb.control(this.indicator.description),
additionalDescription: this.fb.control(this.indicator.additionalDescription),
visibility: this.fb.control(this.indicator.visibility),
indicatorPaths: this.fb.array([]),
width: this.fb.control(this.indicator.width, Validators.required),
@ -736,8 +741,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
}
public get isAdministrator(): boolean {
return this.properties.environment == 'development' || Session.isPortalAdministrator(this.user);
// return Session.isPortalAdministrator(this.user) || Session.isMonitorCurator(this.user) || Session.isCommunityCurator(this.user)
return Session.isPortalAdministrator(this.user) || Session.isMonitorCurator(this.user) || Session.isCommunityCurator(this.user)
}
refreshIndicator() {

View File

@ -27,7 +27,7 @@
class="uk-margin-top uk-margin-small-right uk-visible-toggle"
[class.uk-active]="topicIndex == i"
[class.uk-text-bold]="topicIndex == i">
<a [routerLink]="'../' + topic.alias" class="uk-flex">
<a [routerLink]="'/admin/'+stakeholder.alias + '/indicators/' + topic.alias" class="uk-flex">
<span *ngIf="topic.icon" class="menu_icon">
<!-- <span [innerHTML]="satinizeHTML(topic.icon)"></span>-->
</span>

View File

@ -16,13 +16,9 @@ export class AdminDashboardGuard implements CanActivate, CanLoad {
}
check(path: string): Observable<boolean> | boolean {
/* //Argiro testing
if(properties.environment == "development"){
return true;
}*/
if (Session.isLoggedIn()) {
const obs = this.userManagementService.getUserInfo(false).pipe(map(user => {
return (Session.isPortalAdministrator(user) || Session.isCommunityCurator(user) || Session.isMonitorCurator(user));
return (Session.isPortalAdministrator(user) || Session.isCommunityCurator(user) || Session.isMonitorCurator(user) || Session.isKindOfMonitorManager(user));
}));
obs.pipe(filter(isLoggedIn => !isLoggedIn)).subscribe(() => {
this.router.navigate(['/user-info'], {queryParams: {'errorCode': LoginErrorCodes.NOT_ADMIN, 'redirectUrl':path}});

View File

@ -506,7 +506,7 @@ export class IndicatorUtils {
return values.length > 1;
}
generateIndicatorByForm(form: any, indicatorPaths: IndicatorPath[], type:IndicatorType, addParameters:boolean = true ): Indicator {
let indicator: Indicator = new Indicator(form.name, form.description, type,
let indicator: Indicator = new Indicator(form.name, form.description, form.additionalDescription, type,
form.width, form.visibility, indicatorPaths, form.defaultId);
indicator._id = form._id;
form.indicatorPaths.forEach((indicatorPath, index) => {

View File

@ -6,7 +6,7 @@
.stakeholderPage {
--primary-color: var(--theme-secondary-color);
--secondary-color: var(--theme-primary-color);
--secondary-color: var(--theme-secondary-color);
}
/*Stakeholder Specific*/
.publicationsSearchForm{
@ -302,3 +302,8 @@ li.selectedVisibility::before {
padding: 0px 2px 3px 0px;
}
.descriptionIcon{
position: absolute;
bottom: 3px;
left: 3px;
}

View File

@ -49,13 +49,13 @@ export let properties: EnvProperties = {
vocabulariesAPI: "https://dev-openaire.d4science.org/provision/mvc/vocabularies/",
piwikBaseUrl: "https://analytics.openaire.eu/piwik.php?idsite=",
piwikSiteId: "80",
/*registryUrl: 'http://mpagasas.di.uoa.gr:8080/dnet-openaire-users-1.0.0-SNAPSHOT/api/registry/',
registryUrl: 'http://mpagasas.di.uoa.gr:8080/dnet-openaire-users-1.0.0-SNAPSHOT/api/registry/',
loginUrl: "http://mpagasas.di.uoa.gr:8180/dnet-login/openid_connect_login",
userInfoUrl: "http://mpagasas.di.uoa.gr:8080/dnet-openaire-users-1.0.0-SNAPSHOT/api/users/getUserInfo?accessToken=",
logoutUrl: 'http://mpagasas.di.uoa.gr:8180/dnet-login/openid_logout',*/
loginUrl: "http://dl170.madgik.di.uoa.gr:8180/dnet-login/openid_connect_login",
logoutUrl: 'http://mpagasas.di.uoa.gr:8180/dnet-login/openid_logout',
/* loginUrl: "http://dl170.madgik.di.uoa.gr:8180/dnet-login/openid_connect_login",
userInfoUrl: "http://dl170.madgik.di.uoa.gr:8180/dnet-openaire-users-1.0.0-SNAPSHOT/api/users/getUserInfo?accessToken=",
logoutUrl: "https://aai.openaire.eu/proxy/saml2/idp/SingleLogoutService.php?ReturnTo=",
logoutUrl: "https://aai.openaire.eu/proxy/saml2/idp/SingleLogoutService.php?ReturnTo=",*/
cookieDomain: ".di.uoa.gr",
feedbackmail: "openaire.test@gmail.com",
cacheUrl: "http://scoobydoo.di.uoa.gr:3000/get?url=",