[umbrella]: Change manage stakeholders to support umbrella and dependent profiles. Add umbrella sidebar menu item in admin. Add hasDashboard guard to handle depdendent stakeholders. Add filtered-stakeholders-base component and use it in manage stakehodlerds and umbrella components.
This commit is contained in:
parent
472eeef326
commit
96e63ae8c0
|
@ -148,6 +148,7 @@ export class PageContentComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
|
||||
calcStickyFooterOffset(element) {
|
||||
this.footer_height = element.offsetHeight;
|
||||
this.cdr.detectChanges();
|
||||
return window.innerHeight - this.footer_height;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import {Notification} from "../../../notifications/notifications";
|
|||
import {NotificationHandler} from "../../../utils/notification-handler";
|
||||
import {StatsProfilesService} from "../../utils/services/stats-profiles.service";
|
||||
import {StakeholderBaseComponent} from "../../utils/stakeholder-base.component";
|
||||
import {StakeholderCategory} from "../../utils/indicator-utils";
|
||||
|
||||
@Component({
|
||||
selector: 'edit-stakeholder',
|
||||
|
@ -43,9 +44,8 @@ import {StakeholderBaseComponent} from "../../utils/stakeholder-base.component";
|
|||
</div>
|
||||
<ng-container *ngIf="isCurator">
|
||||
<div class="uk-width-1-3@m">
|
||||
<div *ngIf="statsProfiles" input [formInput]="stakeholderFb.get('statsProfile')"
|
||||
[type]="'select'"
|
||||
[options]="statsProfiles"
|
||||
<div input [formInput]="stakeholderFb.get('statsProfile')"
|
||||
[type]="'select'" [options]="statsProfiles" [disabled]="statsProfiles?.length === 0">
|
||||
placeholder="Stats Profile"></div>
|
||||
</div>
|
||||
<div class="uk-width-1-3@m">
|
||||
|
@ -150,13 +150,13 @@ import {StakeholderBaseComponent} from "../../utils/stakeholder-base.component";
|
|||
export class EditStakeholderComponent extends StakeholderBaseComponent {
|
||||
@Input()
|
||||
public disableAlias: boolean = false;
|
||||
public stakeholderCategory: StakeholderCategory;
|
||||
public stakeholderFb: UntypedFormGroup;
|
||||
public secure: boolean = false;
|
||||
public defaultStakeholdersOptions: Option[];
|
||||
public defaultStakeholders: Stakeholder[];
|
||||
public alias: string[];
|
||||
public stakeholder: Stakeholder;
|
||||
public isDefault: boolean;
|
||||
public isNew: boolean;
|
||||
public isFull: boolean;
|
||||
public loading: boolean = false;
|
||||
|
@ -186,7 +186,7 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
|
|||
super.ngOnDestroy();
|
||||
}
|
||||
|
||||
public init(stakeholder: Stakeholder, alias: string[], defaultStakeholders: Stakeholder[], isDefault: boolean, isNew: boolean, isFull: boolean = false) {
|
||||
public init(stakeholder: Stakeholder, alias: string[], defaultStakeholders: Stakeholder[], stakeholderCategory: StakeholderCategory, isNew: boolean, isFull: boolean = false) {
|
||||
this.reset();
|
||||
this.deleteCurrentPhoto = false;
|
||||
this.stakeholder = stakeholder;
|
||||
|
@ -195,7 +195,7 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
|
|||
}
|
||||
this.alias = alias;
|
||||
this.defaultStakeholders = defaultStakeholders;
|
||||
this.isDefault = isDefault;
|
||||
this.stakeholderCategory = stakeholderCategory;
|
||||
this.isNew = isNew;
|
||||
this.isFull = isFull;
|
||||
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
|
||||
|
@ -229,15 +229,13 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
|
|||
this.alias.filter(alias => alias !== this.stakeholder.alias)
|
||||
)]
|
||||
),
|
||||
isDefault: this.fb.control((this.isDefault)),
|
||||
visibility: this.fb.control(this.stakeholder.visibility, Validators.required),
|
||||
type: this.fb.control(this.stakeholder.type, Validators.required),
|
||||
funderType: this.fb.control(this.stakeholder.funderType),
|
||||
topics: this.fb.control(this.stakeholder.topics),
|
||||
isUpload: this.fb.control(this.stakeholder.isUpload),
|
||||
copy: this.fb.control(this.stakeholder.copy),
|
||||
logoUrl: this.fb.control(this.stakeholder.logoUrl),
|
||||
umbrella: this.fb.control(!!this.stakeholder.umbrella)
|
||||
logoUrl: this.fb.control(this.stakeholder.logoUrl)
|
||||
});
|
||||
if (this.stakeholder.isUpload) {
|
||||
this.stakeholderFb.get('logoUrl').clearValidators();
|
||||
|
@ -265,7 +263,6 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
|
|||
}));
|
||||
this.stakeholderFb.setControl('defaultId', this.fb.control(this.stakeholder.defaultId, (this.isDefault && !this.isNew) ? [] : Validators.required));
|
||||
if (!this.isNew) {
|
||||
this.stakeholderFb.get('umbrella').disable();
|
||||
this.notification = NotificationUtils.editStakeholder(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name);
|
||||
this.notify.reset(this.notification.message);
|
||||
if (this.isAdmin) {
|
||||
|
@ -300,6 +297,10 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
|
|||
}));
|
||||
}
|
||||
|
||||
public get isDefault() {
|
||||
return this.stakeholderCategory?.value === 'templates';
|
||||
}
|
||||
|
||||
public get isAdmin() {
|
||||
return Session.isPortalAdministrator(this.user);
|
||||
}
|
||||
|
@ -324,7 +325,7 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
|
|||
|
||||
public get canChangeCopy(): boolean {
|
||||
return this.isCurator &&
|
||||
!this.stakeholderFb.get('isDefault').getRawValue() &&
|
||||
!this.isDefault &&
|
||||
this.stakeholderFb.get('defaultId').getRawValue() &&
|
||||
this.stakeholderFb.get('defaultId').getRawValue() !== '-1';
|
||||
}
|
||||
|
@ -376,14 +377,16 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
|
|||
public saveStakeholder(callback: Function, errorCallback: Function = null) {
|
||||
if (this.isNew) {
|
||||
let copyId = null;
|
||||
if (this.stakeholderFb.getRawValue().isDefault) {
|
||||
if (this.isDefault) {
|
||||
copyId = this.stakeholderFb.getRawValue().defaultId !== '-1'?this.stakeholderFb.getRawValue().defaultId:null;
|
||||
this.stakeholderFb.get('defaultId').setValue(null);
|
||||
this.stakeholderFb.removeControl('isDefault');
|
||||
}
|
||||
this.removePhoto();
|
||||
this.subscriptions.push(this.stakeholderService.buildStakeholder(this.properties.monitorServiceAPIURL,
|
||||
this.stakeholderFb.getRawValue(), copyId, true).subscribe(stakeholder => {
|
||||
this.stakeholderFb.getRawValue(), copyId,
|
||||
this.stakeholderCategory.value !== 'dependent',
|
||||
this.stakeholderCategory.value === 'umbrella')
|
||||
.subscribe(stakeholder => {
|
||||
this.notification.entity = stakeholder._id;
|
||||
this.notification.stakeholder = stakeholder.alias;
|
||||
this.notification.stakeholderType = stakeholder.type;
|
||||
|
|
|
@ -42,7 +42,7 @@ export class GeneralComponent extends BaseComponent implements OnInit {
|
|||
}
|
||||
|
||||
public reset() {
|
||||
this.editStakeholderComponent.init(this.stakeholder, this.alias, [], this.stakeholder.defaultId == null, false, true)
|
||||
this.editStakeholderComponent.init(this.stakeholder, this.alias, [], null, false, true)
|
||||
}
|
||||
|
||||
public save() {
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
import {Component, OnInit, QueryList, ViewChildren} from "@angular/core";
|
||||
import {ManageStakeholders} from "../../monitor/entities/stakeholder";
|
||||
import {Session} from "../../login/utils/helper.class";
|
||||
import {StakeholderBaseComponent} from "../utils/stakeholder-base.component";
|
||||
import {StakeholderService} from "../../monitor/services/stakeholder.service";
|
||||
import {UserManagementService} from "../../services/user-management.service";
|
||||
import {ActivatedRoute} from "@angular/router";
|
||||
import {Title} from "@angular/platform-browser";
|
||||
import {Option} from "../../sharedComponents/input/input.component";
|
||||
import {zip} from "rxjs";
|
||||
import {StringUtils} from "../../utils/string-utils.class";
|
||||
import {StakeholderCategory} from "../utils/indicator-utils";
|
||||
import {ManageStakeholdersComponent} from "./manageStakeholders.component";
|
||||
|
||||
@Component({
|
||||
selector: `manage-all`,
|
||||
template: `
|
||||
<div page-content>
|
||||
<div header class="uk-margin-bottom">
|
||||
<sidebar-mobile-toggle class="uk-margin-top uk-hidden@m uk-display-block"></sidebar-mobile-toggle>
|
||||
<div *ngIf="stakeholderCategories.length > 2" class="uk-margin-remove-bottom uk-margin-medium-top">
|
||||
<slider-tabs [type]="'dynamic'" (activeEmitter)="active = $event">
|
||||
<slider-tab *ngFor="let category of stakeholderCategories" [tabTitle]="category.plural"
|
||||
[tabId]="category.value" [active]="active === category.value"></slider-tab>
|
||||
</slider-tabs>
|
||||
</div>
|
||||
</div>
|
||||
<div actions>
|
||||
<div class="uk-section-xsmall">
|
||||
<div class="uk-flex uk-flex-center uk-flex-wrap uk-flex-middle uk-flex-between@m">
|
||||
<div class="uk-width-medium">
|
||||
<div input type="select" placeholder="Type" [disabled]="loading"
|
||||
[options]="types" [(value)]="type">
|
||||
</div>
|
||||
</div>
|
||||
<div search-input [(value)]="keyword" [expandable]="true"
|
||||
[disabled]="loading" [placeholder]="'Search ' + entities.stakeholders" searchInputClass="outer"
|
||||
class="uk-width-1-3@xl uk-width-2-5@l uk-width-1-2@m uk-width-1-1 uk-flex uk-flex-right"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div inner>
|
||||
<div *ngIf="loading" class="uk-margin-medium-top uk-padding-large message">
|
||||
<loading></loading>
|
||||
</div>
|
||||
<div *ngIf="!loading" uk-height-match="target: .titleContainer; row: false">
|
||||
<div uk-height-match="target: .logoContainer; row: false">
|
||||
<div *ngIf="!isManager()" class="message">
|
||||
<h4 class="uk-text-center">
|
||||
No profiles to manage yet
|
||||
</h4>
|
||||
</div>
|
||||
<ng-container *ngIf="isManager()">
|
||||
<manage-stakeholders *ngFor="let category of categories"
|
||||
[(aliases)]="aliases" [stakeholderCategory]="category"
|
||||
[user]="user" [keyword]="keyword" [type]="type"
|
||||
[defaultStakeholders]="manageStakeholders.templates"
|
||||
[(stakeholders)]="manageStakeholders[category.value]">
|
||||
</manage-stakeholders>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export class ManageAllComponent extends StakeholderBaseComponent implements OnInit {
|
||||
public loading: boolean = true;
|
||||
public stakeholderCategories: StakeholderCategory[] = this.stakeholderUtils.stakeholderCategories;
|
||||
public active: 'all' | 'templates' | 'standalone' | 'umbrella' | 'dependent' = 'all';
|
||||
public aliases: string[];
|
||||
public manageStakeholders: ManageStakeholders;
|
||||
public user = null;
|
||||
/**
|
||||
* Filters
|
||||
*/
|
||||
public keyword: string;
|
||||
public type: string = 'all';
|
||||
public types: Option[] = [{value: 'all', label: 'All'}].concat(this.stakeholderUtils.types);
|
||||
@ViewChildren(ManageStakeholdersComponent) manageStakeholdersList: QueryList<ManageStakeholdersComponent>;
|
||||
|
||||
public readonly StringUtils = StringUtils;
|
||||
|
||||
constructor(private stakeholderService: StakeholderService,
|
||||
private userManagementService: UserManagementService,
|
||||
protected _route: ActivatedRoute,
|
||||
protected _title: Title) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.title = 'Manage Profiles';
|
||||
this.setMetadata();
|
||||
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
|
||||
this.user = user;
|
||||
if(!this.isManager()) {
|
||||
this.stakeholderCategories = [];
|
||||
} else if(!this.isCurator()) {
|
||||
this.stakeholderCategories = this.stakeholderCategories.filter(category => category.value !== 'templates');
|
||||
}
|
||||
}));
|
||||
let data = zip(
|
||||
this.stakeholderService.getMyStakeholders(this.properties.monitorServiceAPIURL),
|
||||
this.stakeholderService.getAlias(this.properties.monitorServiceAPIURL)
|
||||
);
|
||||
this.subscriptions.push(data.subscribe(res => {
|
||||
this.manageStakeholders = res[0];
|
||||
this.aliases = res[1];
|
||||
this.loading = false;
|
||||
}, error => {
|
||||
this.loading = false;
|
||||
}));
|
||||
}
|
||||
|
||||
public isManager(): boolean {
|
||||
return this.isCurator() || (Session.isKindOfMonitorManager(this.user));
|
||||
}
|
||||
|
||||
public isCurator(): boolean {
|
||||
return this.isAdmin() || Session.isMonitorCurator(this.user);
|
||||
}
|
||||
|
||||
public isAdmin(): boolean {
|
||||
return Session.isPortalAdministrator(this.user);
|
||||
}
|
||||
|
||||
get categories(): StakeholderCategory[] {
|
||||
return this.stakeholderCategories.filter(category => category.value !== 'all' &&
|
||||
(this.active === 'all' || category.value === this.active));
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import {NgModule} from '@angular/core';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard';
|
||||
import {ManageStakeholdersComponent} from "./manageStakeholders.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: '',
|
||||
component: ManageStakeholdersComponent,
|
||||
canDeactivate: [PreviousRouteRecorder]
|
||||
}
|
||||
])
|
||||
]
|
||||
})
|
||||
export class ManageStakeholdersRoutingModule {
|
||||
}
|
|
@ -1,156 +1,81 @@
|
|||
<div page-content>
|
||||
<div header>
|
||||
<sidebar-mobile-toggle class="uk-margin-top uk-hidden@m uk-display-block"></sidebar-mobile-toggle>
|
||||
<div *ngIf="isCurator()" class="uk-margin-remove-bottom uk-margin-medium-top">
|
||||
<slider-tabs [type]="'dynamic'" (activeEmitter)="tab = $event">
|
||||
<slider-tab tabTitle="All" [tabId]="'all'" [active]="tab === 'all'"></slider-tab>
|
||||
<slider-tab tabTitle="Profile templates" [tabId]="'templates'"
|
||||
[active]="tab === 'templates'"></slider-tab>
|
||||
<slider-tab tabTitle="Profiles" [tabId]="'profiles'" [active]="tab === 'profiles'"></slider-tab>
|
||||
</slider-tabs>
|
||||
<div class="uk-section">
|
||||
<div class="uk-flex uk-flex-middle uk-flex-between uk-margin-bottom">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<h4 class="uk-margin-remove">{{stakeholderCategory.plural}}</h4>
|
||||
<a *ngIf="stakeholderCategory.tooltip" class="uk-margin-small-left uk-button uk-button-link" [attr.uk-tooltip]="stakeholderCategory.tooltip">
|
||||
<icon name="info" [flex]="true" [ratio]="0.8"></icon>
|
||||
</a>
|
||||
</div>
|
||||
<paging-no-load *ngIf="filteredStakeholders?.length > pageSize"
|
||||
(pageChange)="updateCurrentPage($event)"
|
||||
[currentPage]="currentPage" [size]="pageSize"
|
||||
[totalResults]="filteredStakeholders.length">
|
||||
</paging-no-load>
|
||||
</div>
|
||||
<div actions>
|
||||
<div class="uk-section-xsmall">
|
||||
<div class="uk-flex uk-flex-center uk-flex-wrap uk-flex-middle uk-flex-between@m">
|
||||
<div class="uk-width-medium uk-margin-small-bottom">
|
||||
<div input type="select" placeholder="Type" [disabled]="loading"
|
||||
[options]="typeOptions" [formInput]="filters.get('type')">
|
||||
</div>
|
||||
</div>
|
||||
<div search-input [searchControl]="filters.get('keyword')" [expandable]="true" [disabled]="loading"
|
||||
placeholder="Search Profiles" searchInputClass="outer"
|
||||
class="uk-width-1-3@xl uk-width-2-5@l uk-width-1-2@m uk-width-1-1 uk-flex uk-flex-right"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div inner>
|
||||
<div *ngIf="loading" class="uk-margin-medium-top uk-padding-large">
|
||||
<loading></loading>
|
||||
</div>
|
||||
<div *ngIf="!loading" uk-height-match="target: .titleContainer; row: false">
|
||||
<div uk-height-match="target: .logoContainer; row: false">
|
||||
<div *ngIf="tab != 'profiles' && isCurator()" class="uk-section">
|
||||
<div class="uk-flex uk-flex-middle uk-flex-between uk-margin-bottom">
|
||||
<h4 class="uk-margin-remove">Profile Templates</h4>
|
||||
<paging-no-load *ngIf="displayDefaultStakeholders?.length > pageSize"
|
||||
(pageChange)="updateCurrentTemplatesPage($event)"
|
||||
[currentPage]="currentTemplatesPage" [size]="pageSize"
|
||||
[totalResults]="displayDefaultStakeholders.length">
|
||||
</paging-no-load>
|
||||
</div>
|
||||
<div class="uk-grid uk-child-width-1-3@l uk-child-width-1-2@m uk-child-width-1-1 uk-grid-match"
|
||||
uk-grid>
|
||||
<ng-template ngFor
|
||||
[ngForOf]="displayDefaultStakeholders.slice((currentTemplatesPage-1)*pageSize, currentTemplatesPage*pageSize)"
|
||||
let-stakeholder>
|
||||
<ng-container
|
||||
*ngTemplateOutlet="stakeholderBox; context: {stakeholder:stakeholder}"></ng-container>
|
||||
</ng-template>
|
||||
<div *ngIf="!loading && isCurator()">
|
||||
<ng-container
|
||||
*ngTemplateOutlet="newBox; context: {text:'Create a new default profile.', isDefault:true}"></ng-container>
|
||||
<div class="uk-grid uk-grid-small uk-child-width-1-4@l uk-child-width-1-3@m uk-child-width-1-1 uk-grid-match" uk-grid>
|
||||
<div *ngFor="let stakeholder of filteredStakeholders.slice((currentPage-1)*pageSize, currentPage*pageSize)">
|
||||
<div class="uk-card uk-card-default uk-card-body uk-position-relative" [ngClass]="stakeholder.type">
|
||||
<div class="uk-position-top-right uk-margin-small-right uk-margin-small-top">
|
||||
<a class="uk-link-reset uk-flex uk-flex-middle">
|
||||
<icon *ngIf="showVisibility" [flex]="true"
|
||||
[name]="stakeholderUtils.visibilityIcon.get(stakeholder.visibility)" ratio="0.6"></icon>
|
||||
<icon [flex]="true" name="more_vert"></icon>
|
||||
</a>
|
||||
<div #element class="uk-dropdown" uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0;">
|
||||
<ul class="uk-nav uk-dropdown-nav">
|
||||
<li>
|
||||
<a (click)="editStakeholder(stakeholder); hide(element)">Edit</a>
|
||||
</li>
|
||||
<li *ngIf="isCurator && stakeholderUtils.isCachingIndicators">
|
||||
<a (click)="createReport(stakeholder);hide(element)">Cache Indicators</a>
|
||||
</li>
|
||||
<li *ngIf="showVisibility" class="uk-nav-divider"></li>
|
||||
<ng-template *ngIf="showVisibility" ngFor [ngForOf]="stakeholderUtils.visibilities" let-v>
|
||||
<li [class.uk-active]="stakeholder.visibility === v.value">
|
||||
<a (click)="changeStakeholderStatus(stakeholder, v.value);hide(element)">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<icon [flex]="true" [name]="v.icon" ratio="0.6"></icon>
|
||||
<span class="uk-margin-small-left uk-width-expand">{{v.label}}</span>
|
||||
<icon *ngIf="stakeholder.visibility === v.value" [flex]="true" name="done"
|
||||
class="uk-text-secondary" ratio="0.8"></icon>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ng-template>
|
||||
<hr *ngIf="isManager(stakeholder)" class="uk-nav-divider">
|
||||
<li *ngIf="isManager(stakeholder)"><a
|
||||
(click)="deleteStakeholderOpen(stakeholder);hide(element)">Delete</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="!isManager()" class="message">
|
||||
<h4 class="uk-text-center">
|
||||
No profiles to manage yet
|
||||
</h4>
|
||||
</div>
|
||||
<div *ngIf="tab != 'templates' && isManager()" class="uk-section">
|
||||
<div class="uk-flex uk-flex-middle uk-flex-between uk-margin-bottom">
|
||||
<h4 class="uk-margin-remove">Profiles</h4>
|
||||
<paging-no-load *ngIf="displayStakeholders?.length > pageSize"
|
||||
(pageChange)="updateCurrentPage($event)"
|
||||
[currentPage]="currentPage" [size]="pageSize"
|
||||
[totalResults]="displayStakeholders.length">
|
||||
</paging-no-load>
|
||||
</div>
|
||||
<div class="uk-grid uk-grid-match uk-child-width-1-3@l uk-child-width-1-2@m uk-child-width-1-1"
|
||||
uk-grid>
|
||||
<ng-template ngFor
|
||||
[ngForOf]="displayStakeholders.slice((currentPage-1)*pageSize, currentPage*pageSize)"
|
||||
let-stakeholder>
|
||||
<ng-container
|
||||
*ngTemplateOutlet="stakeholderBox; context: {stakeholder:stakeholder}"></ng-container>
|
||||
</ng-template>
|
||||
<div *ngIf="!loading && isCurator()">
|
||||
<ng-container *ngTemplateOutlet="newBox; context: {text:'Create a new profile by selecting the type ('+typesAsString+') and ' +
|
||||
'select indicators based on a default or a blank profile.', isDefault:false}"></ng-container>
|
||||
<a class="uk-display-block uk-text-center uk-link-reset" [routerLink]="'/admin/' + stakeholder.alias">
|
||||
<div class="titleContainer uk-h6 uk-margin-remove-bottom uk-margin-top multi-line-ellipsis lines-2">
|
||||
<p *ngIf="stakeholder.name" class="uk-margin-remove">
|
||||
{{stakeholder.name}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="logoContainer uk-margin-top uk-flex uk-flex-column uk-flex-center uk-flex-middle">
|
||||
<img [src]="stakeholder | logoUrl" class="uk-blend-multiply" style="max-height: 60px;">
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="isCurator()">
|
||||
<div class="uk-card uk-card-default uk-text-center uk-card-body clickable"
|
||||
(click)="editStakeholder(null)">
|
||||
<div class="uk-text-small uk-text-muted">
|
||||
{{message}}
|
||||
</div>
|
||||
<div class="uk-margin-top uk-margin-small-bottom">
|
||||
<span class="uk-text-secondary">
|
||||
<icon name="add" [ratio]="3"></icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ng-template #stakeholderBox let-stakeholder="stakeholder">
|
||||
<div *ngIf="stakeholder">
|
||||
<div class="uk-card uk-card-default uk-card-body uk-position-relative" [ngClass]="stakeholder.type">
|
||||
<div class="uk-position-top-right uk-margin-small-right uk-margin-small-top">
|
||||
<a class="uk-link-reset uk-flex uk-flex-middle">
|
||||
<icon *ngIf="showVisibility" [flex]="true"
|
||||
[name]="stakeholderUtils.visibilityIcon.get(stakeholder.visibility)" ratio="0.6"></icon>
|
||||
<icon [flex]="true" name="more_vert"></icon>
|
||||
</a>
|
||||
<div #element class="uk-dropdown"
|
||||
uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0;">
|
||||
<ul class="uk-nav uk-dropdown-nav">
|
||||
<li>
|
||||
<a (click)="editStakeholder(stakeholder, !stakeholder.defaultId); hide(element)">Edit</a>
|
||||
</li>
|
||||
<li *ngIf="isCurator && stakeholderUtils.isCachingIndicators">
|
||||
<a (click)="createReport(stakeholder);hide(element)">Cache Indicators</a>
|
||||
</li>
|
||||
<li *ngIf="showVisibility" class="uk-nav-divider"></li>
|
||||
<ng-template *ngIf="showVisibility" ngFor [ngForOf]="stakeholderUtils.visibilities" let-v>
|
||||
<li [class.uk-active]="stakeholder.visibility === v.value">
|
||||
<a (click)="changeStakeholderStatus(stakeholder, v.value);hide(element)">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<icon [flex]="true" [name]="v.icon" ratio="0.6"></icon>
|
||||
<span class="uk-margin-small-left uk-width-expand">{{v.label}}</span>
|
||||
<icon *ngIf="stakeholder.visibility === v.value" [flex]="true" name="done"
|
||||
class="uk-text-secondary" ratio="0.8"></icon>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ng-template>
|
||||
<hr *ngIf="isProfileManager(stakeholder)" class="uk-nav-divider">
|
||||
<li *ngIf="isProfileManager(stakeholder)"><a
|
||||
(click)="deleteStakeholderOpen(stakeholder);hide(element)">Delete</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<a class="uk-display-block uk-text-center uk-link-reset" [routerLink]="'/admin/' + stakeholder.alias">
|
||||
<div class="titleContainer uk-h6 uk-margin-remove-bottom uk-margin-top multi-line-ellipsis lines-2">
|
||||
<p *ngIf="stakeholder.name" class="uk-margin-remove">
|
||||
{{stakeholder.name}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="logoContainer uk-margin-top uk-flex uk-flex-column uk-flex-center uk-flex-middle">
|
||||
<img [src]="stakeholder | logoUrl" class="uk-blend-multiply" style="max-height: 80px;">
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
<ng-template #newBox let-text="text" let-isDefault="isDefault">
|
||||
<ng-container *ngIf="!loading">
|
||||
<div class="uk-card uk-card-default uk-text-center uk-card-body clickable"
|
||||
(click)="editStakeholder(null, isDefault)">
|
||||
<div class="uk-text-small uk-text-muted">
|
||||
{{text}}
|
||||
</div>
|
||||
<div class="uk-margin-medium-top uk-margin-small-bottom">
|
||||
<span class="uk-text-secondary">
|
||||
<icon name="add" [ratio]="3"></icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
<modal-alert #editStakeholderModal [large]="true" classTitle="uk-background-primary uk-light"
|
||||
(alertOutput)="editStakeholderComponent.save(callback)"
|
||||
(cancelOutput)="editStakeholderComponent.removePhoto()"
|
||||
|
|
|
@ -1,53 +1,41 @@
|
|||
import {Component, OnDestroy, OnInit, ViewChild} from "@angular/core";
|
||||
import {ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild} from "@angular/core";
|
||||
import {StakeholderService} from "../../monitor/services/stakeholder.service";
|
||||
import {Stakeholder, Visibility} from "../../monitor/entities/stakeholder";
|
||||
import {zip} from "rxjs";
|
||||
import {UntypedFormBuilder, UntypedFormGroup} from "@angular/forms";
|
||||
import {AlertModal} from "../../utils/modal/alert";
|
||||
import {Option} from "../../sharedComponents/input/input.component";
|
||||
import {Title} from "@angular/platform-browser";
|
||||
import {UserManagementService} from "../../services/user-management.service";
|
||||
import {Session} from "../../login/utils/helper.class";
|
||||
import {EditStakeholderComponent} from "../general/edit-stakeholder/edit-stakeholder.component";
|
||||
import {ActivatedRoute} from "@angular/router";
|
||||
import {CacheIndicatorsService} from "../utils/cache-indicators/cache-indicators.service";
|
||||
import {NotificationHandler} from "../../utils/notification-handler";
|
||||
import {StakeholderBaseComponent} from "../utils/stakeholder-base.component";
|
||||
import {FilteredStakeholdersBaseComponent} from "../shared/filtered-stakeholders-base.component";
|
||||
|
||||
type Tab = 'all' | 'templates'| 'profiles';
|
||||
|
||||
declare var UIkit;
|
||||
|
||||
@Component({
|
||||
selector: 'home',
|
||||
templateUrl: "./manageStakeholders.component.html",
|
||||
styleUrls: ["./manageStakeholders.component.less"]
|
||||
selector: 'manage-stakeholders',
|
||||
templateUrl: "manageStakeholders.component.html",
|
||||
styleUrls: ["manageStakeholders.component.less"]
|
||||
})
|
||||
export class ManageStakeholdersComponent extends StakeholderBaseComponent implements OnInit, OnDestroy {
|
||||
public loading: boolean = true;
|
||||
public deleteLoading: boolean = false;
|
||||
export class ManageStakeholdersComponent extends FilteredStakeholdersBaseComponent {
|
||||
@Input()
|
||||
public defaultStakeholders: Stakeholder[];
|
||||
public stakeholders: Stakeholder[];
|
||||
public alias: string[];
|
||||
/**
|
||||
* List of aliases
|
||||
* */
|
||||
@Input()
|
||||
public aliases: string[];
|
||||
@Output()
|
||||
public aliasesChange = new EventEmitter<string[]>();
|
||||
/**
|
||||
* Edit/Create/Delete
|
||||
* */
|
||||
public message: string;
|
||||
public deleteLoading: boolean = false;
|
||||
public stakeholder: Stakeholder;
|
||||
public index: number;
|
||||
@Input()
|
||||
public user = null;
|
||||
public tab: Tab = 'all';
|
||||
public currentPage: number = 1;
|
||||
public currentTemplatesPage: number = 1;
|
||||
public pageSize: number = 15;
|
||||
public typeOptions: Option[];
|
||||
/**
|
||||
* Filtered Stakeholders
|
||||
*/
|
||||
public displayDefaultStakeholders: Stakeholder[] = [];
|
||||
public displayStakeholders: Stakeholder[] = [];
|
||||
/**
|
||||
* Top filters
|
||||
*/
|
||||
public filters: UntypedFormGroup;
|
||||
public callback: Function;
|
||||
|
||||
/**
|
||||
* Grid or List View
|
||||
*/
|
||||
|
@ -57,133 +45,44 @@ export class ManageStakeholdersComponent extends StakeholderBaseComponent implem
|
|||
|
||||
constructor(private stakeholderService: StakeholderService,
|
||||
private cacheIndicatorsService: CacheIndicatorsService,
|
||||
private userManagementService: UserManagementService,
|
||||
protected _route: ActivatedRoute,
|
||||
protected _title: Title,
|
||||
private fb: UntypedFormBuilder) {
|
||||
protected cdr: ChangeDetectorRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.typeOptions = [{value: 'all', label: 'All'}].concat(this.stakeholderUtils.types);
|
||||
this.buildFilters();
|
||||
this.title = 'Manage Profiles';
|
||||
this.setMetadata();
|
||||
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
|
||||
this.user = user;
|
||||
}));
|
||||
let data = zip(
|
||||
this.stakeholderService.getMyStakeholders(this.properties.monitorServiceAPIURL),
|
||||
this.stakeholderService.getAlias(this.properties.monitorServiceAPIURL)
|
||||
);
|
||||
this.subscriptions.push(data.subscribe(res => {
|
||||
this.defaultStakeholders = res[0].templates;
|
||||
this.stakeholders = res[0].standalone;
|
||||
this.displayDefaultStakeholders = res[0].templates;
|
||||
this.displayStakeholders = res[0].standalone;
|
||||
this.alias = res[1];
|
||||
this.loading = false;
|
||||
}, error => {
|
||||
this.loading = false;
|
||||
}));
|
||||
super.ngOnInit();
|
||||
if(this.stakeholderCategory.value === 'templates') {
|
||||
this.message = 'Create a new ' + this.stakeholderCategory.name + ' profile.';
|
||||
} else {
|
||||
this.message = 'Create a new ' + this.stakeholderCategory.name +
|
||||
' profile by selecting a type and generate indicators based on a default or a blank profile.';
|
||||
}
|
||||
}
|
||||
|
||||
hide(element: any) {
|
||||
UIkit.dropdown(element).hide();
|
||||
}
|
||||
|
||||
private buildFilters() {
|
||||
this.filters = this.fb.group({
|
||||
status: this.fb.control('all'),
|
||||
type: this.fb.control('all'),
|
||||
keyword: this.fb.control('')
|
||||
});
|
||||
this.subscriptions.push(this.filters.get('status').valueChanges.subscribe(value => {
|
||||
this.filtering();
|
||||
}));
|
||||
this.subscriptions.push(this.filters.get('type').valueChanges.subscribe(value => {
|
||||
this.filtering();
|
||||
}));
|
||||
this.subscriptions.push(this.filters.get('keyword').valueChanges.subscribe(value => {
|
||||
this.filtering();
|
||||
}));
|
||||
|
||||
changed() {
|
||||
this.aliasesChange.emit(this.aliases);
|
||||
super.changed();
|
||||
}
|
||||
|
||||
private filterByStatus(stakeholders: Stakeholder[], value): Stakeholder[] {
|
||||
if (value === 'all') {
|
||||
return stakeholders;
|
||||
} else {
|
||||
return stakeholders.filter(stakeholder => stakeholder.visibility == value);
|
||||
}
|
||||
}
|
||||
|
||||
private filterByType(stakeholders: Stakeholder[], value) {
|
||||
if(value == 'all') {
|
||||
return stakeholders;
|
||||
} else {
|
||||
return stakeholders.filter(item => item.type == value);
|
||||
}
|
||||
}
|
||||
|
||||
private filterByKeyword(stakeholders: Stakeholder[], value): Stakeholder[] {
|
||||
if (!value) {
|
||||
return stakeholders;
|
||||
} else {
|
||||
return stakeholders.filter(stakeholder =>
|
||||
stakeholder.name && stakeholder.name.toLowerCase().includes(value.toLowerCase()) ||
|
||||
stakeholder.type && stakeholder.type.toLowerCase().includes(value.toLowerCase()) ||
|
||||
stakeholder.index_id && stakeholder.index_id.toLowerCase().includes(value.toLowerCase()) ||
|
||||
stakeholder.index_shortName && stakeholder.index_shortName.toLowerCase().includes(value.toLowerCase()) ||
|
||||
stakeholder.index_name && stakeholder.index_name.toLowerCase().includes(value.toLowerCase())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
filtering() {
|
||||
let keyword = this.filters.get('keyword').value;
|
||||
let type = this.filters.get('type').value;
|
||||
let status = this.filters.get('status').value;
|
||||
let displayStakeholders = this.stakeholders;
|
||||
let displayDefaultStakeholders = this.defaultStakeholders;
|
||||
|
||||
displayStakeholders = this.filterByKeyword(displayStakeholders, keyword);
|
||||
displayStakeholders = this.filterByType(displayStakeholders, type);
|
||||
displayStakeholders = this.filterByStatus(displayStakeholders, status);
|
||||
displayDefaultStakeholders = this.filterByKeyword(displayDefaultStakeholders, keyword);
|
||||
displayDefaultStakeholders = this.filterByType(displayDefaultStakeholders, type);
|
||||
displayDefaultStakeholders = this.filterByStatus(displayDefaultStakeholders, status);
|
||||
|
||||
this.displayStakeholders = displayStakeholders;
|
||||
this.displayDefaultStakeholders = displayDefaultStakeholders;
|
||||
this.currentPage = 1;
|
||||
this.currentTemplatesPage = 1;
|
||||
}
|
||||
|
||||
public editStakeholder(stakeholder: Stakeholder = null, isDefault: boolean = false) {
|
||||
if (isDefault) {
|
||||
this.index = (stakeholder) ? this.defaultStakeholders.findIndex(value => value._id === stakeholder._id) : -1;
|
||||
} else {
|
||||
this.index = (stakeholder) ? this.stakeholders.findIndex(value => value._id === stakeholder._id) : -1;
|
||||
}
|
||||
public editStakeholder(stakeholder: Stakeholder = null) {
|
||||
this.index = (stakeholder) ? this.stakeholders.findIndex(value => value._id === stakeholder._id) : -1;
|
||||
if (!stakeholder) {
|
||||
this.stakeholder = new Stakeholder(null, null, null,
|
||||
null, null, null, null, null);
|
||||
} else {
|
||||
this.stakeholder = stakeholder;
|
||||
}
|
||||
this.editStakeholderComponent.init(this.stakeholder, this.alias, this.defaultStakeholders, isDefault, this.index === -1);
|
||||
this.editStakeholderComponent.init(this.stakeholder, this.aliases, this.defaultStakeholders, this.stakeholderCategory, this.index === -1);
|
||||
if (this.index !== -1) {
|
||||
this.callback = (stakeholder: Stakeholder) => {
|
||||
let index: number;
|
||||
if (stakeholder.defaultId == null) {
|
||||
index = this.alias.findIndex(value => value == this.defaultStakeholders[this.index].alias);
|
||||
this.defaultStakeholders[this.index] = stakeholder;
|
||||
} else {
|
||||
index = this.alias.findIndex(value => value == this.stakeholders[this.index].alias);
|
||||
this.stakeholders[this.index] = stakeholder;
|
||||
}
|
||||
let index: number = this.aliases.findIndex(value => value == this.stakeholders[this.index].alias);
|
||||
this.stakeholders[this.index] = stakeholder;
|
||||
if(index != -1) {
|
||||
this.alias[index] = stakeholder.alias;
|
||||
this.aliases[index] = stakeholder.alias;
|
||||
}
|
||||
this.editStakeholderModal.cancel();
|
||||
};
|
||||
|
@ -191,16 +90,12 @@ export class ManageStakeholdersComponent extends StakeholderBaseComponent implem
|
|||
this.editStakeholderModal.okButtonText = 'Save Changes';
|
||||
} else {
|
||||
this.callback = (stakeholder: Stakeholder) => {
|
||||
if (stakeholder.defaultId === null) {
|
||||
this.defaultStakeholders.push(stakeholder);
|
||||
} else {
|
||||
this.stakeholders.push(stakeholder);
|
||||
}
|
||||
this.alias.push(stakeholder.alias);
|
||||
this.stakeholders.push(stakeholder);
|
||||
this.aliases.push(stakeholder.alias)
|
||||
this.changed();
|
||||
this.editStakeholderModal.cancel();
|
||||
this.filtering();
|
||||
};
|
||||
this.editStakeholderModal.alertTitle = 'Create a new ' + (isDefault?'Default ':'') + 'Profile';
|
||||
this.editStakeholderModal.alertTitle = 'Create a new ' + this.stakeholderCategory.name + ' profile';
|
||||
this.editStakeholderModal.okButtonText = 'Create';
|
||||
}
|
||||
this.editStakeholderModal.cancelButtonText = 'Cancel';
|
||||
|
@ -231,26 +126,18 @@ export class ManageStakeholdersComponent extends StakeholderBaseComponent implem
|
|||
|
||||
public deleteStakeholder() {
|
||||
this.deleteLoading = true;
|
||||
if (!this.stakeholder.defaultId) {
|
||||
this.index = (this.stakeholder) ? this.defaultStakeholders.findIndex(value => value._id === this.stakeholder._id) : -1;
|
||||
} else {
|
||||
this.index = (this.stakeholder) ? this.stakeholders.findIndex(value => value._id === this.stakeholder._id) : -1;
|
||||
}
|
||||
this.index = (this.stakeholder) ? this.stakeholders.findIndex(value => value._id === this.stakeholder._id) : -1;
|
||||
this.subscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, [this.stakeholder._id]).subscribe(() => {
|
||||
UIkit.notification(this.stakeholder.name+ ' has been <b>successfully deleted</b>', {
|
||||
status: 'success',
|
||||
timeout: 6000,
|
||||
pos: 'bottom-right'
|
||||
});
|
||||
if (!this.stakeholder.defaultId) {
|
||||
this.defaultStakeholders.splice(this.index, 1);
|
||||
} else {
|
||||
this.stakeholders.splice(this.index, 1);
|
||||
}
|
||||
this.alias = this.alias.filter(item => item !== this.stakeholder.alias);
|
||||
this.stakeholders.splice(this.index, 1);
|
||||
this.aliases = this.aliases.filter(item => item !== this.stakeholder.alias);
|
||||
this.changed();
|
||||
this.deleteLoading = false;
|
||||
this.deleteStakeholderModal.cancel();
|
||||
this.filtering();
|
||||
}, error => {
|
||||
UIkit.notification('An error has occurred. Please try again later', {
|
||||
status: 'danger',
|
||||
|
@ -281,33 +168,16 @@ export class ManageStakeholdersComponent extends StakeholderBaseComponent implem
|
|||
});
|
||||
}));
|
||||
}
|
||||
|
||||
public isManager(): boolean {
|
||||
return this.isCurator() || (Session.isKindOfMonitorManager(this.user));
|
||||
}
|
||||
|
||||
public isProfileManager(stakeholder: Stakeholder): boolean {
|
||||
|
||||
public isManager(stakeholder: Stakeholder): boolean {
|
||||
return this.isCurator() || (Session.isManager(stakeholder.type, stakeholder.alias, this.user));
|
||||
}
|
||||
|
||||
|
||||
public isCurator(): boolean {
|
||||
return this.isAdmin() || Session.isMonitorCurator(this.user);
|
||||
}
|
||||
|
||||
|
||||
public isAdmin(): boolean {
|
||||
return Session.isPortalAdministrator(this.user);
|
||||
}
|
||||
|
||||
get typesAsString() {
|
||||
return this.stakeholderUtils.types.slice(0, this.stakeholderUtils.types.length - 1).map(type => type.label).join(', ') +
|
||||
' or ' + this.stakeholderUtils.types[this.stakeholderUtils.types.length - 1].label
|
||||
}
|
||||
|
||||
public updateCurrentPage($event) {
|
||||
this.currentPage = $event.value;
|
||||
}
|
||||
|
||||
public updateCurrentTemplatesPage($event) {
|
||||
this.currentTemplatesPage = $event.value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import {NgModule} from "@angular/core";
|
||||
import {ManageStakeholdersComponent} from "./manageStakeholders.component";
|
||||
import {ManageStakeholdersRoutingModule} from "./manageStakeholders-routing.module";
|
||||
import {CommonModule} from "@angular/common";
|
||||
import {RouterModule} from "@angular/router";
|
||||
import {InputModule} from "../../sharedComponents/input/input.module";
|
||||
|
@ -19,11 +17,20 @@ import {
|
|||
import {SliderTabsModule} from "../../sharedComponents/tabs/slider-tabs.module";
|
||||
import {EditStakeholderModule} from "../general/edit-stakeholder/edit-stakeholder.module";
|
||||
import {PagingModule} from "../../utils/paging.module";
|
||||
import {PreviousRouteRecorder} from "../../utils/piwik/previousRouteRecorder.guard";
|
||||
import {ManageAllComponent} from "./manage-all.component";
|
||||
import {ManageStakeholdersComponent} from "./manageStakeholders.component";
|
||||
|
||||
@NgModule({
|
||||
declarations: [ManageStakeholdersComponent],
|
||||
declarations: [ManageAllComponent, ManageStakeholdersComponent],
|
||||
imports: [
|
||||
ManageStakeholdersRoutingModule,
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: '',
|
||||
component: ManageAllComponent,
|
||||
canDeactivate: [PreviousRouteRecorder]
|
||||
}
|
||||
]),
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
InputModule,
|
||||
|
@ -40,7 +47,7 @@ import {PagingModule} from "../../utils/paging.module";
|
|||
PagingModule
|
||||
],
|
||||
providers: [],
|
||||
exports: [ManageStakeholdersComponent]
|
||||
exports: [ManageAllComponent]
|
||||
})
|
||||
export class ManageStakeholdersModule {
|
||||
constructor(private iconsService: IconsService) {
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
import {
|
||||
ChangeDetectorRef,
|
||||
Directive,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnInit,
|
||||
Output,
|
||||
SimpleChanges
|
||||
} from "@angular/core";
|
||||
import {StakeholderBaseComponent} from "../utils/stakeholder-base.component";
|
||||
import {StakeholderCategory} from "../utils/indicator-utils";
|
||||
import {Stakeholder, StakeholderType} from "../../monitor/entities/stakeholder";
|
||||
|
||||
@Directive()
|
||||
export class FilteredStakeholdersBaseComponent extends StakeholderBaseComponent implements OnInit, OnChanges {
|
||||
/**
|
||||
* Filtering
|
||||
* */
|
||||
@Input()
|
||||
public keyword: string;
|
||||
@Input()
|
||||
public type: StakeholderType | 'all' = 'all';
|
||||
/** Stakeholders */
|
||||
@Input()
|
||||
public stakeholderCategory: StakeholderCategory;
|
||||
@Input()
|
||||
public stakeholders: Stakeholder[];
|
||||
@Output()
|
||||
public stakeholdersChange: EventEmitter<Stakeholder[]> = new EventEmitter<Stakeholder[]>();
|
||||
/**
|
||||
* Filtered Stakeholders
|
||||
*/
|
||||
public filteredStakeholders: Stakeholder[] = [];
|
||||
public currentPage: number = 1;
|
||||
public pageSize: number = 16;
|
||||
|
||||
protected cdr: ChangeDetectorRef
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.filterByKeyword();
|
||||
this.filterByType();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if(changes.type) {
|
||||
this.filterByType();
|
||||
}
|
||||
if(changes.keyword) {
|
||||
this.filterByKeyword();
|
||||
}
|
||||
if(changes.stakeholders) {
|
||||
this.filterByKeyword();
|
||||
this.filterByType();
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
}
|
||||
|
||||
changed() {
|
||||
this.stakeholdersChange.emit(this.stakeholders);
|
||||
this.filterByType();
|
||||
this.filterByKeyword();
|
||||
}
|
||||
|
||||
public filterByType() {
|
||||
if(this.type == 'all') {
|
||||
this.filteredStakeholders = this.stakeholders;
|
||||
} else {
|
||||
this.filteredStakeholders = this.stakeholders.filter(item => item.type == this.type);
|
||||
}
|
||||
this.currentPage = 1;
|
||||
}
|
||||
|
||||
public filterByKeyword(): void{
|
||||
if (!this.keyword) {
|
||||
this.filteredStakeholders = this.stakeholders;
|
||||
} else {
|
||||
this.filteredStakeholders = this.stakeholders.filter(stakeholder =>
|
||||
stakeholder.name?.toLowerCase().includes(this.keyword.toLowerCase()) ||
|
||||
stakeholder.alias?.toLowerCase().includes(this.keyword.toLowerCase()) ||
|
||||
stakeholder.index_id?.toLowerCase().includes(this.keyword.toLowerCase()) ||
|
||||
stakeholder.index_shortName?.toLowerCase().includes(this.keyword.toLowerCase()) ||
|
||||
stakeholder.index_name?.toLowerCase().includes(this.keyword.toLowerCase())
|
||||
);
|
||||
}
|
||||
this.currentPage = 1;
|
||||
}
|
||||
|
||||
public updateCurrentPage($event) {
|
||||
this.currentPage = $event.value;
|
||||
}
|
||||
}
|
|
@ -227,8 +227,7 @@
|
|||
</div>
|
||||
<ul *ngIf="stakeholder.topics.length > 0 && stakeholder.topics[topicIndex].categories.length > 0 && stakeholder.topics[topicIndex].categories[categoryIndex]"
|
||||
transition-group class="uk-tab uk-margin-xsmall-top" [id]="'subCategories'">
|
||||
<ng-template ngFor [ngForOf]=" stakeholder.topics[topicIndex].categories[categoryIndex].subCategories"
|
||||
let-subCategory let-i="index">
|
||||
<ng-container *ngFor="let subCategory of stakeholder.topics[topicIndex].categories[categoryIndex].subCategories; let i=index">
|
||||
<li class="uk-visible-toggle uk-flex" [class.uk-active]="subCategoryIndex === i" transition-group-item>
|
||||
<a (click)="chooseSubcategory(i)">
|
||||
<span class="uk-text-uppercase">{{subCategory.name}}</span>
|
||||
|
@ -321,7 +320,7 @@
|
|||
</div>
|
||||
</span>
|
||||
</li>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
<li *ngIf="isCurator && isEditable">
|
||||
<a (click)="editSubCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle">
|
||||
<icon name="add" [flex]="true"></icon>
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
import {ChangeDetectorRef, Component, EventEmitter, Input, Output} from "@angular/core";
|
||||
import {FilteredStakeholdersBaseComponent} from "../shared/filtered-stakeholders-base.component";
|
||||
|
||||
@Component({
|
||||
selector: 'filtered-stakeholders',
|
||||
template: `
|
||||
<div class="uk-section">
|
||||
<div class="uk-flex uk-flex-middle uk-flex-between uk-margin-bottom">
|
||||
<div *ngIf="stakeholderCategory" class="uk-flex uk-flex-middle">
|
||||
<h4 class="uk-margin-remove">{{ stakeholderCategory.plural }}</h4>
|
||||
<a *ngIf="stakeholderCategory.tooltip" class="uk-margin-small-left uk-button uk-button-link"
|
||||
[attr.uk-tooltip]="stakeholderCategory.tooltip">
|
||||
<icon name="info" [flex]="true" [ratio]="0.8"></icon>
|
||||
</a>
|
||||
</div>
|
||||
<paging-no-load *ngIf="filteredStakeholders?.length > pageSize"
|
||||
(pageChange)="updateCurrentPage($event)"
|
||||
[currentPage]="currentPage" [size]="pageSize"
|
||||
[totalResults]="filteredStakeholders.length">
|
||||
</paging-no-load>
|
||||
</div>
|
||||
<div class="uk-grid uk-grid-small uk-child-width-1-4@l uk-child-width-1-3@m uk-child-width-1-1 uk-grid-match"
|
||||
uk-grid>
|
||||
<div *ngFor="let stakeholder of filteredStakeholders.slice((currentPage-1)*pageSize, currentPage*pageSize)">
|
||||
<div class="uk-card uk-card-default">
|
||||
<div class="uk-card-body uk-position-relative">
|
||||
<div class="uk-position-top-right uk-margin-small-right uk-margin-small-top">
|
||||
<span class="uk-link-reset uk-flex uk-flex-middle">
|
||||
<icon *ngIf="showVisibility" [flex]="true"
|
||||
[name]="stakeholderUtils.visibilityIcon.get(stakeholder.visibility)"
|
||||
ratio="0.6"></icon>
|
||||
</span>
|
||||
</div>
|
||||
<div class="uk-display-block uk-text-center">
|
||||
<div class="titleContainer uk-h6 uk-margin-remove-bottom uk-margin-top multi-line-ellipsis lines-2">
|
||||
<p *ngIf="stakeholder.name" class="uk-margin-remove">
|
||||
{{ stakeholder.name }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="logoContainer uk-margin-top uk-flex uk-flex-column uk-flex-center uk-flex-middle">
|
||||
<img [src]="stakeholder | logoUrl" class="uk-blend-multiply"
|
||||
style="max-height: 60px;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="(add && !stakeholder['added']) || (remove && stakeholder['added'])" class="uk-card-footer uk-padding-remove-vertical">
|
||||
<div class="uk-grid uk-grid-small uk-flex-nowrap uk-grid-divider uk-flex-right" uk-grid>
|
||||
<div *ngIf="add && !stakeholder['added']">
|
||||
<div class="uk-padding-small uk-padding-remove-horizontal">
|
||||
<button class="uk-button uk-button-link uk-flex uk-flex-middle"
|
||||
(click)="added.emit(stakeholder._id)">
|
||||
<icon name="add" [flex]="true"></icon>
|
||||
<span class="uk-margin-xsmall-left">Add</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="remove && stakeholder['added']">
|
||||
<div class="uk-padding-small uk-padding-remove-horizontal">
|
||||
<button class="uk-button uk-button-link uk-flex uk-flex-middle"
|
||||
(click)="removed.emit(stakeholder._id)">
|
||||
<icon name="delete" [flex]="true"></icon>
|
||||
<span class="uk-margin-xsmall-left">Remove</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="filteredStakeholders.length === 0">
|
||||
<div class="uk-position-relative uk-section">
|
||||
<h6 class="uk-position-center">No {{ entities.stakeholders }} have been found.</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export class FilteredStakeholdersComponent extends FilteredStakeholdersBaseComponent {
|
||||
@Output()
|
||||
public added: EventEmitter<string> = new EventEmitter<string>();
|
||||
@Output()
|
||||
public removed: EventEmitter<string> = new EventEmitter<string>();
|
||||
@Input()
|
||||
public add: boolean = false;
|
||||
@Input()
|
||||
public remove: boolean = false;
|
||||
|
||||
constructor(protected cdr: ChangeDetectorRef) {
|
||||
super();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,329 @@
|
|||
import {ChangeDetectorRef, Component, OnInit, ViewChild} from "@angular/core";
|
||||
import {StakeholderBaseComponent} from "../utils/stakeholder-base.component";
|
||||
import {ActivatedRoute, Router} from "@angular/router";
|
||||
import {Title} from "@angular/platform-browser";
|
||||
import {StakeholderService} from "../../monitor/services/stakeholder.service";
|
||||
import {ManageStakeholders, Stakeholder, StakeholderType} from "../../monitor/entities/stakeholder";
|
||||
import {Session, User} from "../../login/utils/helper.class";
|
||||
import {UserManagementService} from "../../services/user-management.service";
|
||||
import {FormBuilder, UntypedFormGroup, Validators} from "@angular/forms";
|
||||
import {AlertModal} from "../../utils/modal/alert";
|
||||
import {NotificationHandler} from "../../utils/notification-handler";
|
||||
import {Option} from "../../sharedComponents/input/input.component";
|
||||
import {IDeactivateComponent} from "../../utils/can-exit.guard";
|
||||
import {FullScreenModalComponent} from "../../utils/modal/full-screen-modal/full-screen-modal.component";
|
||||
import {map} from "rxjs/operators";
|
||||
import {StakeholderCategory} from "../utils/indicator-utils";
|
||||
import {HelperFunctions} from "../../utils/HelperFunctions.class";
|
||||
|
||||
declare var UIkit;
|
||||
|
||||
@Component({
|
||||
selector: 'umbrella',
|
||||
template: `
|
||||
<div page-content>
|
||||
<div header class="uk-margin-medium-top">
|
||||
<ul *ngIf="umbrella" class="uk-tab uk-margin-xsmall-top">
|
||||
<ng-container *ngFor="let type of umbrella.types; let i=index">
|
||||
<li class="uk-visible-toggle uk-flex" [class.uk-active]="activeIndex === i">
|
||||
<a (click)="chooseType(i)">
|
||||
<span class="uk-text-uppercase">{{ stakeholderUtils.entities[type] }}</span>
|
||||
</a>
|
||||
<div class="uk-flex uk-flex-column uk-flex-center uk-margin-small-left"
|
||||
[class.uk-invisible-hover]="activeIndex !== i"
|
||||
(click)="$event.stopPropagation();$event.preventDefault()">
|
||||
<a class="uk-link-reset uk-flex uk-flex-middle">
|
||||
<icon [flex]="true" name="more_vert"></icon>
|
||||
</a>
|
||||
<div #element
|
||||
uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; container: body">
|
||||
<ul class="uk-nav uk-dropdown-nav">
|
||||
<li>
|
||||
<a (click)="deleteTypeOpen(i); hide(element)">
|
||||
<div class="uk-flex uk-flex-middle">
|
||||
<icon [flex]="true" name="delete" ratio="0.6"></icon>
|
||||
<span class="uk-margin-small-left uk-width-expand">Remove</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ng-container>
|
||||
<li *ngIf="isCurator">
|
||||
<a (click)="addTypeOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle">
|
||||
<icon name="add" [flex]="true"></icon>
|
||||
<span class="uk-text-uppercase">Add type</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div actions class="uk-flex uk-flex-right@m uk-flex-center">
|
||||
<button class="uk-button uk-button-primary" (click)="manageStakeholdersOpen()">
|
||||
Manage {{ entities.stakeholders }}
|
||||
</button>
|
||||
</div>
|
||||
<div inner class="uk-section">
|
||||
<div *ngIf="children == null" class="message">
|
||||
<h6>No types yet. Add a type to start.</h6>
|
||||
</div>
|
||||
<div *ngIf="children != null" uk-height-match="target: .titleContainer; row: false">
|
||||
<div uk-height-match="target: .logoContainer; row: false">
|
||||
<filtered-stakeholders [remove]="true" (removed)="removeStakeholder($event)"
|
||||
[keyword]="keyword" [stakeholders]="children">
|
||||
</filtered-stakeholders>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<modal-alert #deleteTypeModal classTitle="uk-background-primary uk-light" (alertOutput)="deleteType()"
|
||||
[overflowBody]="false">
|
||||
<div [class.uk-invisible]="loading" class="uk-position-relative">
|
||||
<div *ngIf="loading">
|
||||
<loading class="uk-position-center"></loading>
|
||||
</div>
|
||||
You are about to remove <span class="uk-text-bold">{{ entities[umbrella.types[index]] }}</span> from the
|
||||
umbrella of {{ stakeholder.name }}.
|
||||
All the profiles added to this type will be removed too.
|
||||
Are you sure you want to proceed?
|
||||
</div>
|
||||
</modal-alert>
|
||||
<modal-alert #addTypeModal classTitle="uk-background-primary uk-light" (alertOutput)="addType()"
|
||||
[okDisabled]="updateFb && (updateFb.invalid || updateFb.pristine)">
|
||||
<div *ngIf="loading" class="uk-position-relative uk-height-large">
|
||||
<loading class="uk-position-center"></loading>
|
||||
</div>
|
||||
<div *ngIf="updateFb" [class.uk-hidden]="loading"
|
||||
class="uk-grid uk-padding uk-padding-remove-horizontal uk-child-width-1-1" [formGroup]="updateFb"
|
||||
uk-grid>
|
||||
<div input [formInput]="updateFb.get('type')" class="uk-width-1-1"
|
||||
placeholder="Type" [options]="types" type="select"></div>
|
||||
</div>
|
||||
</modal-alert>
|
||||
<fs-modal #manageStakeholdersModal>
|
||||
<div *ngIf="loading" class="uk-position-relative uk-height-large">
|
||||
<loading class="uk-position-center"></loading>
|
||||
</div>
|
||||
<ng-container *ngIf="!loading && manageStakeholders">
|
||||
<div class="uk-section-xsmall">
|
||||
<div class="uk-flex uk-flex-center uk-flex-wrap uk-flex-middle uk-flex-right@m">
|
||||
<div search-input [(value)]="keyword" [expandable]="true"
|
||||
[disabled]="loading" [placeholder]="'Search ' + entities.stakeholders"
|
||||
searchInputClass="outer"
|
||||
class="uk-width-1-3@xl uk-width-2-5@l uk-width-1-2@m uk-width-1-1 uk-flex uk-flex-right"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div uk-height-match="target: .titleContainer; row: false">
|
||||
<div uk-height-match="target: .logoContainer; row: false">
|
||||
<filtered-stakeholders *ngFor="let category of categories" [add]="true" (added)="addStakeholder($event)"
|
||||
[stakeholderCategory]="category" [remove]="true"
|
||||
(removed)="removeStakeholder($event)"
|
||||
[keyword]="keyword" [(stakeholders)]="manageStakeholders[category.value]">
|
||||
</filtered-stakeholders>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</fs-modal>
|
||||
`
|
||||
})
|
||||
export class UmbrellaComponent extends StakeholderBaseComponent implements OnInit, IDeactivateComponent {
|
||||
public loading: boolean = false;
|
||||
public stakeholder: Stakeholder;
|
||||
public user: User;
|
||||
public types: Option[] = [];
|
||||
public manageStakeholders: ManageStakeholders;
|
||||
public activeIndex: number = 0;
|
||||
public index: number;
|
||||
public updateFb: UntypedFormGroup;
|
||||
public keyword: string;
|
||||
@ViewChild('addTypeModal', {static: true}) addTypeModal: AlertModal;
|
||||
@ViewChild('deleteTypeModal', {static: true}) deleteTypeModal: AlertModal;
|
||||
@ViewChild('manageStakeholdersModal', {static: true}) manageStakeholdersModal: FullScreenModalComponent;
|
||||
|
||||
constructor(protected _route: ActivatedRoute,
|
||||
protected _router: Router,
|
||||
protected _title: Title,
|
||||
private fb: FormBuilder,
|
||||
private userManagementService: UserManagementService,
|
||||
private stakeholderService: StakeholderService,
|
||||
private cdr: ChangeDetectorRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
|
||||
this.user = user;
|
||||
}));
|
||||
this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
|
||||
if (stakeholder) {
|
||||
this.stakeholder = stakeholder;
|
||||
if (!this.stakeholder.umbrella) {
|
||||
this.navigateToError();
|
||||
} else {
|
||||
this.umbrella = stakeholder.umbrella;
|
||||
}
|
||||
this.title = stakeholder.name + " | Manage Umbrella";
|
||||
this.setMetadata();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
canExit(): boolean {
|
||||
this.stakeholderService.setStakeholder(this.stakeholder);
|
||||
return true;
|
||||
}
|
||||
|
||||
resetUpdateForm(action: "ADD" | "REMOVE" = "ADD", type: StakeholderType = null, child: string = null): void {
|
||||
this.updateFb = this.fb.group({
|
||||
type: this.fb.control(type, Validators.required),
|
||||
action: this.fb.control(action, Validators.required),
|
||||
});
|
||||
if (child) {
|
||||
this.updateFb.addControl("child", this.fb.control(child, Validators.required));
|
||||
}
|
||||
}
|
||||
|
||||
addTypeOpen(): void {
|
||||
this.resetUpdateForm();
|
||||
this.addTypeModal.cancelButtonText = 'Cancel';
|
||||
this.addTypeModal.okButtonLeft = false;
|
||||
this.addTypeModal.alertMessage = false;
|
||||
this.addTypeModal.alertTitle = 'Add a type';
|
||||
this.addTypeModal.stayOpen = true;
|
||||
this.addTypeModal.open();
|
||||
}
|
||||
|
||||
deleteTypeOpen(index: number): void {
|
||||
this.index = index;
|
||||
this.resetUpdateForm("REMOVE", this.umbrella.types[this.index]);
|
||||
this.deleteTypeModal.cancelButtonText = 'No';
|
||||
this.deleteTypeModal.okButtonText = 'Yes';
|
||||
this.deleteTypeModal.alertTitle = 'Remove ' + this.umbrella.types[this.index];
|
||||
this.deleteTypeModal.stayOpen = true;
|
||||
this.deleteTypeModal.open();
|
||||
}
|
||||
|
||||
addType() {
|
||||
this.loading = true;
|
||||
this.updateUmbrella(this.addTypeModal);
|
||||
}
|
||||
|
||||
deleteType() {
|
||||
this.loading = true;
|
||||
this.updateUmbrella(this.deleteTypeModal);
|
||||
}
|
||||
|
||||
addStakeholder(id: string) {
|
||||
this.resetUpdateForm('ADD', this.activeType, id);
|
||||
this.updateUmbrella();
|
||||
}
|
||||
|
||||
removeStakeholder(id: string) {
|
||||
this.resetUpdateForm('REMOVE', this.activeType, id);
|
||||
this.updateUmbrella();
|
||||
}
|
||||
|
||||
public manageStakeholdersOpen() {
|
||||
this.manageStakeholdersModal.title = 'Manage ' + this.entities.stakeholders;
|
||||
this.manageStakeholdersModal.okButtonText = "Done";
|
||||
this.manageStakeholdersModal.okButton = true;
|
||||
this.setManageStakeholders();
|
||||
this.manageStakeholdersModal.open();
|
||||
}
|
||||
|
||||
setManageStakeholders() {
|
||||
this.loading = true;
|
||||
this.subscriptions.push(this.stakeholderService.getMyStakeholders(this.properties.monitorServiceAPIURL, this.activeType).pipe(map(manageStakeholders => {
|
||||
delete manageStakeholders.templates;
|
||||
delete manageStakeholders.umbrella;
|
||||
return manageStakeholders;
|
||||
})).subscribe(manageStakeholders => {
|
||||
this.filterManagedStakeholders(manageStakeholders);
|
||||
this.manageStakeholders.standalone.sort(this.sort);
|
||||
this.manageStakeholders.dependent.sort(this.sort);
|
||||
this.loading = false;
|
||||
}));
|
||||
}
|
||||
|
||||
filterManagedStakeholders(manageStakeholders: ManageStakeholders) {
|
||||
manageStakeholders.standalone.forEach(stakeholder => {
|
||||
stakeholder['added'] = this.children.findIndex(child => child._id === stakeholder._id) !== -1;
|
||||
});
|
||||
manageStakeholders.dependent.forEach(stakeholder => {
|
||||
stakeholder['added'] = this.children.findIndex(child => child._id === stakeholder._id) !== -1;
|
||||
});
|
||||
this.manageStakeholders = manageStakeholders;
|
||||
}
|
||||
|
||||
sort(a: any, b: any): number {
|
||||
if (a['added'] && !b['added']) {
|
||||
return -1;
|
||||
} else if (!a['added'] && b['added']) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
updateUmbrella(modal: AlertModal = null) {
|
||||
this.subscriptions.push(this.stakeholderService.updateUmbrella(this.properties.monitorServiceAPIURL, this.stakeholder._id, this.updateFb.getRawValue())
|
||||
.subscribe(umbrella => {
|
||||
this.loading = false;
|
||||
if(modal) {
|
||||
modal.cancel();
|
||||
}
|
||||
this.umbrella = umbrella;
|
||||
if(!this.activeType) {
|
||||
this.activeIndex = 0;
|
||||
}
|
||||
this.filterManagedStakeholders(this.manageStakeholders);
|
||||
this.cdr.detectChanges();
|
||||
}, error => {
|
||||
this.loading = false;
|
||||
if(modal) {
|
||||
modal.cancel();
|
||||
}
|
||||
NotificationHandler.rise(error.error.message, 'danger');
|
||||
}));
|
||||
}
|
||||
|
||||
hide(element: any) {
|
||||
UIkit.dropdown(element).hide();
|
||||
}
|
||||
|
||||
chooseType(index: number) {
|
||||
this.activeIndex = index;
|
||||
}
|
||||
|
||||
get umbrella() {
|
||||
return this.stakeholder.umbrella;
|
||||
}
|
||||
|
||||
get activeType(): StakeholderType {
|
||||
return this.umbrella.types[this.activeIndex];
|
||||
}
|
||||
|
||||
set umbrella(umbrella) {
|
||||
this.stakeholder.umbrella = HelperFunctions.copy(umbrella);
|
||||
this.types = this.stakeholderUtils.types.filter(type => !umbrella.types.includes(type.value));
|
||||
}
|
||||
|
||||
get isCurator(): boolean {
|
||||
return Session.isPortalAdministrator(this.user) || Session.isCurator(this.stakeholder.type, this.user);
|
||||
}
|
||||
|
||||
get children(): Stakeholder[] {
|
||||
if (this.activeType) {
|
||||
return this.umbrella.children[this.activeType].map(stakeholder => {
|
||||
stakeholder['added'] = true;
|
||||
return stakeholder;
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
get categories(): StakeholderCategory[] {
|
||||
return this.stakeholderUtils.stakeholderCategories.filter(category => category.value === 'standalone' || category.value === 'dependent');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import {NgModule} from "@angular/core";
|
||||
import {CommonModule} from "@angular/common";
|
||||
import {RouterModule} from "@angular/router";
|
||||
import {PreviousRouteRecorder} from "../../utils/piwik/previousRouteRecorder.guard";
|
||||
import {UmbrellaComponent} from "./umbrella.component";
|
||||
import {PageContentModule} from "../../dashboard/sharedComponents/page-content/page-content.module";
|
||||
import {IconsModule} from "../../utils/icons/icons.module";
|
||||
import {AlertModalModule} from "../../utils/modal/alertModal.module";
|
||||
import {LoadingModule} from "../../utils/loading/loading.module";
|
||||
import {ReactiveFormsModule} from "@angular/forms";
|
||||
import {InputModule} from "../../sharedComponents/input/input.module";
|
||||
import {CanExitGuard} from "../../utils/can-exit.guard";
|
||||
import {FullScreenModalModule} from "../../utils/modal/full-screen-modal/full-screen-modal.module";
|
||||
import {LogoUrlPipeModule} from "../../utils/pipes/logoUrlPipe.module";
|
||||
import {PagingModule} from "../../utils/paging.module";
|
||||
import {FilteredStakeholdersComponent} from "./filtered-stakeholders.component";
|
||||
import {SearchInputModule} from "../../sharedComponents/search-input/search-input.module";
|
||||
|
||||
@NgModule({
|
||||
declarations: [UmbrellaComponent, FilteredStakeholdersComponent],
|
||||
imports: [CommonModule, RouterModule.forChild([
|
||||
{path: '', component: UmbrellaComponent, canDeactivate: [PreviousRouteRecorder, CanExitGuard]}
|
||||
]), PageContentModule, IconsModule, AlertModalModule, LoadingModule, ReactiveFormsModule, InputModule, FullScreenModalModule, LogoUrlPipeModule, PagingModule, SearchInputModule],
|
||||
exports: [UmbrellaComponent]
|
||||
})
|
||||
export class UmbrellaModule {}
|
|
@ -43,9 +43,25 @@ export interface OAIndicator {
|
|||
denominator: IndicatorPath;
|
||||
}
|
||||
|
||||
export interface StakeholderCategory {
|
||||
name: string,
|
||||
plural: string,
|
||||
value: 'all' | 'templates' | 'standalone' | 'umbrella' | 'dependent'
|
||||
tooltip?: string
|
||||
}
|
||||
|
||||
export class StakeholderConfiguration {
|
||||
|
||||
public static ENTITIES: Entities = new Entities();
|
||||
public static STAKEHOLDER_CATEGORIES: StakeholderCategory[] = [
|
||||
{name: 'All', plural: 'All', value: 'all'},
|
||||
{name: 'Template', plural: 'Templates', value: 'templates'},
|
||||
{name: 'Standalone', plural: 'Standalone', value: 'standalone'},
|
||||
{name: 'Umbrella', plural: 'Umbrella', value: 'umbrella'},
|
||||
{name: 'Integrated ', plural: 'Integrated', value: 'dependent',
|
||||
tooltip: 'A profile that doesn\'t have his own ' + StakeholderConfiguration.ENTITIES.stakeholder +
|
||||
', but can be integrated into another ' + StakeholderConfiguration.ENTITIES.stakeholder + '.'}
|
||||
];
|
||||
public static TYPES: Option[] = [
|
||||
{value: 'funder', label: StakeholderConfiguration.ENTITIES.funder},
|
||||
{value: 'ri', label: StakeholderConfiguration.ENTITIES.ri},
|
||||
|
@ -68,6 +84,7 @@ export class StakeholderConfiguration {
|
|||
public static NUMBER_MULTI_INDICATOR_PATHS = false;
|
||||
public static CHART_MULTI_INDICATOR_PATHS = true;
|
||||
public static openAccess: Map<string, OAIndicator> = new Map();
|
||||
|
||||
}
|
||||
|
||||
export class StakeholderUtils {
|
||||
|
@ -75,8 +92,12 @@ export class StakeholderUtils {
|
|||
return StakeholderConfiguration.ENTITIES;
|
||||
}
|
||||
|
||||
get stakeholderCategories(): StakeholderCategory[] {
|
||||
return StakeholderConfiguration.STAKEHOLDER_CATEGORIES;
|
||||
}
|
||||
|
||||
get types() {
|
||||
return StakeholderConfiguration.TYPES
|
||||
return StakeholderConfiguration.TYPES;
|
||||
}
|
||||
|
||||
get funderTypes() {
|
||||
|
@ -560,9 +581,9 @@ export class IndicatorUtils {
|
|||
} else if (filterType == "start_year" || filterType == "end_year") {
|
||||
//if has date filter already
|
||||
// if (filterType == "start_year" && parseInt(filterValue) > parseInt(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0])) {
|
||||
queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] = filterValue;
|
||||
queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] = filterValue;
|
||||
// } else if (filterType == "end_year" && parseInt(filterValue) < parseInt(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0])) {
|
||||
queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] = filterValue;
|
||||
queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] = filterValue;
|
||||
// }
|
||||
filterApplied = true;
|
||||
}
|
||||
|
@ -887,6 +908,8 @@ export class IndicatorUtils {
|
|||
return ChartHelper.prefix + "index_id" + ChartHelper.suffix;
|
||||
} else if (currentValue == stakeholder.index_shortName) {
|
||||
return ChartHelper.prefix + "index_shortName" + ChartHelper.suffix;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ export type Format = 'NUMBER' | 'PERCENTAGE';
|
|||
export type Visibility = 'PUBLIC' | 'PRIVATE' | 'RESTRICTED';
|
||||
export type Overlay = 'embed' | 'description' | false;
|
||||
|
||||
export class ManageStakeholder {
|
||||
export class ManageStakeholders {
|
||||
templates: Stakeholder[];
|
||||
standalone: Stakeholder[];
|
||||
dependent: Stakeholder[];
|
||||
|
@ -93,8 +93,8 @@ export class StakeholderInfo extends Stakeholder {
|
|||
}
|
||||
|
||||
export class Umbrella {
|
||||
types: string[];
|
||||
children: any[];
|
||||
types: StakeholderType[];
|
||||
children: any;
|
||||
}
|
||||
|
||||
export class Topic {
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import {Injectable} from "@angular/core";
|
||||
import {ActivatedRouteSnapshot, Router, RouterStateSnapshot, UrlTree} from "@angular/router";
|
||||
import {Observable} from "rxjs";
|
||||
import {map, take, tap} from "rxjs/operators";
|
||||
import {StakeholderService} from "./stakeholder.service";
|
||||
import {properties} from "../../../../environments/environment";
|
||||
import {LinksResolver} from "../../../search/links-resolver";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class HasDashboardGuard {
|
||||
|
||||
constructor(protected router: Router,
|
||||
protected stakeholderService: StakeholderService) {
|
||||
}
|
||||
|
||||
check(path: string, alias: string, type: string, child: string): Observable<boolean> | boolean {
|
||||
let get = this.stakeholderService.getStakeholder(alias);
|
||||
if(child) {
|
||||
get = this.stakeholderService.getChildStakeholder(alias, type, child);
|
||||
}
|
||||
return get.pipe(take(1), map(stakeholder => {
|
||||
return stakeholder.standalone || (!!stakeholder && !!child);
|
||||
}),tap(authorized => {
|
||||
if(!authorized){
|
||||
this.router.navigate([LinksResolver.default.errorLink], {queryParams: {'page': path}});
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
|
||||
return this.check(state.url, route.params.stakeholder, route.params.type, route.params.child);
|
||||
}
|
||||
|
||||
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
|
||||
return this.check(state.url, childRoute.data?.stakeholder?childRoute.data.stakeholder:childRoute.params.stakeholder,
|
||||
childRoute.params.type, childRoute.params.child);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,12 +2,11 @@ import {Injectable} from "@angular/core";
|
|||
import {HttpClient} from "@angular/common/http";
|
||||
import {BehaviorSubject, from, Observable, Subscriber} from "rxjs";
|
||||
import {
|
||||
Indicator,
|
||||
ManageStakeholder,
|
||||
Indicator, ManageStakeholders,
|
||||
Section,
|
||||
Stakeholder,
|
||||
StakeholderInfo,
|
||||
SubCategory,
|
||||
StakeholderInfo, StakeholderType,
|
||||
SubCategory, Umbrella,
|
||||
Visibility
|
||||
} from "../entities/stakeholder";
|
||||
import {HelperFunctions} from "../../utils/HelperFunctions.class";
|
||||
|
@ -26,6 +25,12 @@ export interface MoveIndicator {
|
|||
to: SectionInfo;
|
||||
}
|
||||
|
||||
export interface UpdateUmbrella {
|
||||
type: StakeholderType;
|
||||
action: "ADD" | "REMOVE",
|
||||
child: string
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root"
|
||||
})
|
||||
|
@ -55,11 +60,7 @@ export class StakeholderService {
|
|||
this.sub = this.http.get<Stakeholder>(properties.monitorServiceAPIURL + '/stakeholder/' + encodeURIComponent(alias), CustomOptions.registryOptions()).pipe(map(stakeholder => {
|
||||
return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholder));
|
||||
})).subscribe(stakeholder => {
|
||||
if (stakeholder.standalone) {
|
||||
this.stakeholderSubject.next(stakeholder);
|
||||
} else {
|
||||
this.stakeholderSubject.next(null);
|
||||
}
|
||||
this.stakeholderSubject.next(stakeholder);
|
||||
resolve();
|
||||
}, error => {
|
||||
this.stakeholderSubject.next(null);
|
||||
|
@ -133,8 +134,8 @@ export class StakeholderService {
|
|||
}));
|
||||
}
|
||||
|
||||
getMyStakeholders(url: string, type: string = null): Observable<ManageStakeholder> {
|
||||
return this.http.get<ManageStakeholder>(url + '/my-stakeholder' + ((type) ? ('?type=' + type) : ''), CustomOptions.registryOptions()).pipe(map(manageStakeholder => {
|
||||
getMyStakeholders(url: string, type: string = null): Observable<ManageStakeholders> {
|
||||
return this.http.get<ManageStakeholders>(url + '/my-stakeholder' + ((type) ? ('?type=' + type) : ''), CustomOptions.registryOptions()).pipe(map(manageStakeholder => {
|
||||
return HelperFunctions.copy({
|
||||
templates: Stakeholder.checkIsUpload(manageStakeholder.templates),
|
||||
standalone: Stakeholder.checkIsUpload(manageStakeholder.standalone),
|
||||
|
@ -144,14 +145,15 @@ export class StakeholderService {
|
|||
}));
|
||||
}
|
||||
|
||||
buildStakeholder(url: string, stakeholder: Stakeholder, copyId: string, umbrella: boolean = false): Observable<Stakeholder> {
|
||||
buildStakeholder(url: string, stakeholder: Stakeholder, copyId: string, standalone: boolean = true, umbrella: boolean = false): Observable<Stakeholder> {
|
||||
if (stakeholder.alias && stakeholder.alias.startsWith('/')) {
|
||||
stakeholder.alias = stakeholder.alias.slice(1);
|
||||
}
|
||||
let buildStakeholder = {
|
||||
stakeholder: stakeholder,
|
||||
copyId: copyId,
|
||||
umbrella: umbrella
|
||||
umbrella: umbrella,
|
||||
standalone: standalone
|
||||
}
|
||||
return this.http.post<Stakeholder>(url + '/build-stakeholder', buildStakeholder, CustomOptions.registryOptions()).pipe(map(stakeholder => {
|
||||
return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholder));
|
||||
|
@ -218,6 +220,12 @@ export class StakeholderService {
|
|||
}));
|
||||
}
|
||||
|
||||
updateUmbrella(url: string, id: string, update: UpdateUmbrella): Observable<Umbrella> {
|
||||
return this.http.post<Umbrella>(url + '/' + id + '/umbrella', update, CustomOptions.registryOptions()).pipe(map(umbrella => {
|
||||
return HelperFunctions.copy(umbrella);
|
||||
}));
|
||||
}
|
||||
|
||||
getStakeholderAsObservable(): Observable<Stakeholder> {
|
||||
return this.stakeholderSubject.asObservable();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue