Update to Angular 16 #7
13
angular.json
13
angular.json
|
@ -208,13 +208,16 @@
|
||||||
"main": "server.ts",
|
"main": "server.ts",
|
||||||
"tsConfig": "src/tsconfig.server.json",
|
"tsConfig": "src/tsconfig.server.json",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"optimization": false
|
"optimization": false,
|
||||||
|
"buildOptimizer": false
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"development": {
|
"development": {
|
||||||
"outputHashing": "media",
|
"outputHashing": "media",
|
||||||
"sourceMap": false,
|
"sourceMap": false,
|
||||||
"optimization": true
|
"optimization": true,
|
||||||
|
"vendorChunk": true,
|
||||||
|
"buildOptimizer": true
|
||||||
},
|
},
|
||||||
"beta": {
|
"beta": {
|
||||||
"outputHashing": "media",
|
"outputHashing": "media",
|
||||||
|
@ -225,7 +228,8 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sourceMap": false,
|
"sourceMap": false,
|
||||||
"optimization": true
|
"optimization": true,
|
||||||
|
"buildOptimizer": true
|
||||||
},
|
},
|
||||||
"production": {
|
"production": {
|
||||||
"outputHashing": "media",
|
"outputHashing": "media",
|
||||||
|
@ -236,7 +240,8 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sourceMap": false,
|
"sourceMap": false,
|
||||||
"optimization": true
|
"optimization": true,
|
||||||
|
"buildOptimizer": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defaultConfiguration": ""
|
"defaultConfiguration": ""
|
||||||
|
|
46
package.json
46
package.json
|
@ -21,44 +21,44 @@
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^14.2.3",
|
"@angular/animations": "^16.1.7",
|
||||||
"@angular/cdk": "^14.2.2",
|
"@angular/cdk": "^16.1.6",
|
||||||
"@angular/common": "^14.2.3",
|
"@angular/common": "^16.1.7",
|
||||||
"@angular/compiler": "^14.2.3",
|
"@angular/compiler": "^16.1.7",
|
||||||
"@angular/core": "^14.2.3",
|
"@angular/core": "^16.1.7",
|
||||||
"@angular/forms": "^14.2.3",
|
"@angular/forms": "^16.1.7",
|
||||||
"@angular/localize": "^14.2.3",
|
"@angular/localize": "^16.1.7",
|
||||||
"@angular/material": "^14.2.2",
|
"@angular/material": "^16.1.6",
|
||||||
"@angular/platform-browser": "^14.2.3",
|
"@angular/platform-browser": "^16.1.7",
|
||||||
"@angular/platform-browser-dynamic": "^14.2.3",
|
"@angular/platform-browser-dynamic": "^16.1.7",
|
||||||
"@angular/platform-server": "^14.2.3",
|
"@angular/platform-server": "^16.1.7",
|
||||||
"@angular/router": "^14.2.3",
|
"@angular/router": "^16.1.7",
|
||||||
"@nguniversal/express-engine": "^14.2.0",
|
"@nguniversal/express-engine": "^16.1.1",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"clipboard": "^1.5.16",
|
"clipboard": "^1.5.16",
|
||||||
"core-js": "^2.5.4",
|
"core-js": "^2.5.4",
|
||||||
"express": "^4.15.2",
|
"express": "^4.15.2",
|
||||||
"jquery": "^3.4.1",
|
"jquery": "^3.4.1",
|
||||||
"ng-recaptcha": "^10.0.0",
|
"ng-recaptcha": "^12.0.2",
|
||||||
"ng2-ckeditor": "1.3.7",
|
"ng2-ckeditor": "1.3.7",
|
||||||
"rxjs": "^6.5.1",
|
"rxjs": "^6.5.1",
|
||||||
"ts-md5": "^1.2.0",
|
"ts-md5": "^1.2.0",
|
||||||
"tslib": "^2.0.0",
|
"tslib": "^2.0.0",
|
||||||
"uikit": "3.13.10",
|
"uikit": "3.16.24",
|
||||||
"zone.js": "~0.11.4"
|
"zone.js": "~0.13.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^14.2.3",
|
"@angular-devkit/build-angular": "^16.1.6",
|
||||||
"@angular/cli": "^14.2.3",
|
"@angular/cli": "^16.1.6",
|
||||||
"@angular/compiler-cli": "^14.2.3",
|
"@angular/compiler-cli": "^16.1.7",
|
||||||
"@angular/language-service": "^14.2.3",
|
"@angular/language-service": "^16.1.7",
|
||||||
"@nguniversal/builders": "^14.2.0",
|
"@nguniversal/builders": "^16.1.1",
|
||||||
"@types/ckeditor": "^4.9.10",
|
"@types/ckeditor": "^4.9.10",
|
||||||
"@types/compression": "^1.7.0",
|
"@types/compression": "^1.7.0",
|
||||||
"@types/express": "^4.17.0",
|
"@types/express": "^4.17.0",
|
||||||
"@types/jasmine": "~3.6.0",
|
"@types/jasmine": "~3.6.0",
|
||||||
"@types/jasminewd2": "~2.0.3",
|
"@types/jasminewd2": "~2.0.3",
|
||||||
"@types/node": "^12.11.1",
|
"@types/node": "^16.18.50",
|
||||||
"codelyzer": "^6.0.0",
|
"codelyzer": "^6.0.0",
|
||||||
"jasmine-core": "~3.8.0",
|
"jasmine-core": "~3.8.0",
|
||||||
"jasmine-spec-reporter": "~5.0.0",
|
"jasmine-spec-reporter": "~5.0.0",
|
||||||
|
@ -69,6 +69,6 @@
|
||||||
"karma-jasmine-html-reporter": "^1.6.0",
|
"karma-jasmine-html-reporter": "^1.6.0",
|
||||||
"protractor": "~7.0.0",
|
"protractor": "~7.0.0",
|
||||||
"ts-node": "~7.0.0",
|
"ts-node": "~7.0.0",
|
||||||
"typescript": "~4.6.4"
|
"typescript": "~4.9.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {REQUEST, RESPONSE} from "./src/app/openaireLibrary/utils/tokens";
|
||||||
import {properties} from "./src/environments/environment";
|
import {properties} from "./src/environments/environment";
|
||||||
import axios, {AxiosHeaders} from "axios";
|
import axios, {AxiosHeaders} from "axios";
|
||||||
import {Stakeholder} from "./src/app/openaireLibrary/monitor/entities/stakeholder";
|
import {Stakeholder} from "./src/app/openaireLibrary/monitor/entities/stakeholder";
|
||||||
import {CacheIndicators} from "./src/cache-indicators";
|
import {CacheIndicators} from "./src/app/openaireLibrary/monitor-admin/utils/cache-indicators/cache-indicators";
|
||||||
import {Session, User} from "./src/app/openaireLibrary/login/utils/helper.class";
|
import {Session, User} from "./src/app/openaireLibrary/login/utils/helper.class";
|
||||||
|
|
||||||
var bodyParser = require('body-parser');
|
var bodyParser = require('body-parser');
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
|
||||||
imports: [RouterModule.forChild([
|
imports: [RouterModule.forChild([
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
loadChildren: () => import('../general/general.module').then(m => m.GeneralModule),
|
loadChildren: () => import('../openaireLibrary/monitor-admin/general/general.module').then(m => m.GeneralModule),
|
||||||
pathMatch: 'full'
|
pathMatch: 'full'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -21,7 +21,7 @@ import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matcher: HelperFunctions.routingMatcher(['indicators', 'indicators/:topic']),
|
matcher: HelperFunctions.routingMatcher(['indicators', 'indicators/:topic']),
|
||||||
loadChildren: () => import('../topic/topic.module').then(m => m.TopicModule),
|
loadChildren: () => import('../openaireLibrary/monitor-admin/topic/topic.module').then(m => m.TopicModule),
|
||||||
data: {hasInternalSidebar: true},
|
data: {hasInternalSidebar: true},
|
||||||
pathMatch: 'full'
|
pathMatch: 'full'
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,8 +2,8 @@ import {NgModule} from '@angular/core';
|
||||||
import {RouterModule, Routes} from '@angular/router';
|
import {RouterModule, Routes} from '@angular/router';
|
||||||
import {OpenaireErrorPageComponent} from './error/errorPage.component';
|
import {OpenaireErrorPageComponent} from './error/errorPage.component';
|
||||||
import {AdminLoginGuard} from "./openaireLibrary/login/adminLoginGuard.guard";
|
import {AdminLoginGuard} from "./openaireLibrary/login/adminLoginGuard.guard";
|
||||||
import {AdminDashboardGuard} from "./utils/adminDashboard.guard";
|
|
||||||
import {LoginGuard} from "./openaireLibrary/login/loginGuard.guard";
|
import {LoginGuard} from "./openaireLibrary/login/loginGuard.guard";
|
||||||
|
import {AdminDashboardGuard} from "./openaireLibrary/monitor-admin/utils/adminDashboard.guard";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,23 +2,23 @@
|
||||||
<loading [full]="true"></loading>
|
<loading [full]="true"></loading>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="!loading" [class.monitor]="isFrontPage">
|
<div *ngIf="!loading" [class.monitor]="isFrontPage">
|
||||||
<div class="sidebar_main_swipe uk-background-default" [class.sidebar_main_active]="open && (hasSidebar || hasAdminMenu || hasInternalSidebar)"
|
<div id="modal-container"></div>
|
||||||
[class.sidebar_mini]="!open && (hasSidebar || hasAdminMenu || hasInternalSidebar)" [class.sidebar_hover]="hover">
|
<navbar *ngIf="hasHeader" portal="monitor_dashboard" [header]="menuHeader" [userMenuItems]=userMenuItems [menuItems]="menuItems" [user]="user"
|
||||||
<div id="modal-container"></div>
|
[notificationConfiguration]="isMobile && user && notificationGroupsInitialized?notificationConfiguration:null"></navbar>
|
||||||
|
<div>
|
||||||
<ng-container *ngIf="!isHidden">
|
<ng-container *ngIf="!isHidden">
|
||||||
<navbar *ngIf="hasHeader" portal="monitor_dashboard" [header]="menuHeader" [userMenuItems]=userMenuItems [menuItems]="menuItems" [user]="user"
|
<div class="sidebar_main_swipe uk-flex uk-background-default" [class.sidebar_main_active]="open && (hasSidebar || hasAdminMenu || hasInternalSidebar)"
|
||||||
[notificationConfiguration]="isMobile && user && notificationGroupsInitialized?notificationConfiguration:null"></navbar>
|
[class.sidebar_mini]="!open && (hasSidebar || hasAdminMenu || hasInternalSidebar)" [class.sidebar_hover]="hover">
|
||||||
<div>
|
|
||||||
<dashboard-sidebar *ngIf="stakeholder && isFrontPage && hasSidebar && !hasInternalSidebar" queryParamsHandling="merge" [items]="sideBarItems"
|
<dashboard-sidebar *ngIf="stakeholder && isFrontPage && hasSidebar && !hasInternalSidebar" queryParamsHandling="merge" [items]="sideBarItems"
|
||||||
[activeItem]="activeTopic?activeTopic.alias:null" [activeSubItem]="activeCategory?activeCategory.alias:null"></dashboard-sidebar>
|
[activeItem]="activeTopic?activeTopic.alias:null" [activeSubItem]="activeCategory?activeCategory.alias:null"></dashboard-sidebar>
|
||||||
<dashboard-sidebar *ngIf="hasAdminMenu && !hasInternalSidebar" [items]="adminMenuItems" [backItem]="backItem"></dashboard-sidebar>
|
<dashboard-sidebar *ngIf="hasAdminMenu && !hasInternalSidebar" [items]="adminMenuItems" [backItem]="backItem"></dashboard-sidebar>
|
||||||
<main>
|
<main class="uk-width-1-1">
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
</main>
|
</main>
|
||||||
<bottom id="bottom" *ngIf="isFrontPage" [centered]="true" [properties]="properties" [showMenuItems]="true"></bottom>
|
|
||||||
<notification-sidebar *ngIf="!isMobile && user && notificationGroupsInitialized" [configuration]="notificationConfiguration" [user]="user"></notification-sidebar>
|
|
||||||
<cache-indicators *ngIf="stakeholder && !isFrontPage && isCurator()" [alias]="stakeholder.alias"></cache-indicators>
|
|
||||||
</div>
|
</div>
|
||||||
|
<bottom id="bottom" *ngIf="isFrontPage" [centered]="true" [properties]="properties" [showMenuItems]="true"></bottom>
|
||||||
|
<notification-sidebar *ngIf="!isMobile && user && notificationGroupsInitialized" [configuration]="notificationConfiguration" [user]="user"></notification-sidebar>
|
||||||
|
<cache-indicators *ngIf="stakeholder && !isFrontPage && isCurator()" [alias]="stakeholder.alias"></cache-indicators>
|
||||||
<div *ngIf="view" class="preview uk-text-small uk-flex uk-flex-middle">
|
<div *ngIf="view" class="preview uk-text-small uk-flex uk-flex-middle">
|
||||||
<span>You are currently in a <span class="uk-text-bold">"Preview"</span> mode. <span class="uk-visible@m"><a (click)="removeView()">The current view</a> of this dashboard may differ.</span></span>
|
<span>You are currently in a <span class="uk-text-bold">"Preview"</span> mode. <span class="uk-visible@m"><a (click)="removeView()">The current view</a> of this dashboard may differ.</span></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -18,7 +18,7 @@ import {LinksResolver} from "./search/links-resolver";
|
||||||
import {Header} from "./openaireLibrary/sharedComponents/navigationBar.component";
|
import {Header} from "./openaireLibrary/sharedComponents/navigationBar.component";
|
||||||
import {properties} from "../environments/environment";
|
import {properties} from "../environments/environment";
|
||||||
import {ConfigurationService} from "./openaireLibrary/utils/configuration/configuration.service";
|
import {ConfigurationService} from "./openaireLibrary/utils/configuration/configuration.service";
|
||||||
import {StakeholderUtils} from "./utils/indicator-utils";
|
import {StakeholderUtils} from "./openaireLibrary/monitor-admin/utils/indicator-utils";
|
||||||
import {SmoothScroll} from "./openaireLibrary/utils/smooth-scroll";
|
import {SmoothScroll} from "./openaireLibrary/utils/smooth-scroll";
|
||||||
import {ConnectHelper} from "./openaireLibrary/connect/connectHelper";
|
import {ConnectHelper} from "./openaireLibrary/connect/connectHelper";
|
||||||
import {ResourcesService} from "./openaireLibrary/monitor/services/resources.service";
|
import {ResourcesService} from "./openaireLibrary/monitor/services/resources.service";
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {NgModule} from '@angular/core';
|
import {APP_ID, NgModule} from '@angular/core';
|
||||||
import {FormsModule} from '@angular/forms';
|
import {FormsModule} from '@angular/forms';
|
||||||
import {CommonModule} from '@angular/common';
|
import {CommonModule} from '@angular/common';
|
||||||
import {HTTP_INTERCEPTORS, HttpClientModule} from "@angular/common/http";
|
import {HTTP_INTERCEPTORS, HttpClientModule} from "@angular/common/http";
|
||||||
|
@ -21,7 +21,6 @@ import {HttpInterceptorService} from "./openaireLibrary/http-interceptor.service
|
||||||
import {DEFAULT_TIMEOUT, TimeoutInterceptor} from "./openaireLibrary/timeout-interceptor.service";
|
import {DEFAULT_TIMEOUT, TimeoutInterceptor} from "./openaireLibrary/timeout-interceptor.service";
|
||||||
import {ErrorInterceptorService} from "./openaireLibrary/error-interceptor.service";
|
import {ErrorInterceptorService} from "./openaireLibrary/error-interceptor.service";
|
||||||
import {AdminLoginGuard} from "./openaireLibrary/login/adminLoginGuard.guard";
|
import {AdminLoginGuard} from "./openaireLibrary/login/adminLoginGuard.guard";
|
||||||
import {AdminDashboardGuard} from "./utils/adminDashboard.guard";
|
|
||||||
import {
|
import {
|
||||||
NotificationsSidebarModule
|
NotificationsSidebarModule
|
||||||
} from "./openaireLibrary/notifications/notifications-sidebar/notifications-sidebar.module";
|
} from "./openaireLibrary/notifications/notifications-sidebar/notifications-sidebar.module";
|
||||||
|
@ -29,7 +28,8 @@ import {LoginGuard} from "./openaireLibrary/login/loginGuard.guard";
|
||||||
import {IconsModule} from "./openaireLibrary/utils/icons/icons.module";
|
import {IconsModule} from "./openaireLibrary/utils/icons/icons.module";
|
||||||
import {IconsService} from "./openaireLibrary/utils/icons/icons.service";
|
import {IconsService} from "./openaireLibrary/utils/icons/icons.service";
|
||||||
import {incognito} from "./openaireLibrary/utils/icons/icons";
|
import {incognito} from "./openaireLibrary/utils/icons/icons";
|
||||||
import {CacheIndicatorsModule} from "./cache-indicators/cache-indicators.module";
|
import {AdminDashboardGuard} from "./openaireLibrary/monitor-admin/utils/adminDashboard.guard";
|
||||||
|
import {CacheIndicatorsModule} from "./openaireLibrary/monitor-admin/utils/cache-indicators/cache-indicators.module";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
||||||
|
@ -43,13 +43,14 @@ import {CacheIndicatorsModule} from "./cache-indicators/cache-indicators.module"
|
||||||
NavigationBarModule,
|
NavigationBarModule,
|
||||||
BottomModule,
|
BottomModule,
|
||||||
CookieLawModule,
|
CookieLawModule,
|
||||||
BrowserModule.withServerTransition({appId: 'serverApp'}),
|
BrowserModule,
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
SideBarModule, Schema2jsonldModule, RoleVerificationModule, LoadingModule, NotificationsSidebarModule, IconsModule, CacheIndicatorsModule
|
SideBarModule, Schema2jsonldModule, RoleVerificationModule, LoadingModule, NotificationsSidebarModule, IconsModule, CacheIndicatorsModule
|
||||||
],
|
],
|
||||||
declarations: [AppComponent, OpenaireErrorPageComponent],
|
declarations: [AppComponent, OpenaireErrorPageComponent],
|
||||||
exports: [AppComponent],
|
exports: [AppComponent],
|
||||||
providers: [
|
providers: [
|
||||||
|
{provide: APP_ID, useValue: 'monitor-dashboard'},
|
||||||
AdminLoginGuard, AdminDashboardGuard, LoginGuard,
|
AdminLoginGuard, AdminDashboardGuard, LoginGuard,
|
||||||
{
|
{
|
||||||
provide: HTTP_INTERCEPTORS,
|
provide: HTTP_INTERCEPTORS,
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
@import (reference) "~src/assets/openaire-theme/less/_import-variables.less";
|
|
||||||
|
|
||||||
.cache-progress {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
right: 0;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
z-index: @global-z-index;
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
import {Component, Inject, Input, OnChanges, OnDestroy, OnInit, PLATFORM_ID, SimpleChanges} from "@angular/core";
|
|
||||||
import {Report} from "../../cache-indicators";
|
|
||||||
import {CacheIndicatorsService} from "../utils/services/cache-indicators.service";
|
|
||||||
import {interval, Subject, Subscription} from "rxjs";
|
|
||||||
import {map, switchMap, takeUntil} from "rxjs/operators";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'cache-indicators',
|
|
||||||
template: `
|
|
||||||
<div *ngIf="report" class="cache-progress">
|
|
||||||
<div class="uk-position-relative" [attr.uk-tooltip]="'Caching indicators process for ' + alias">
|
|
||||||
<div class="uk-progress-circle" [attr.percentage]="report.percentage?report.percentage:0" [style]="'--percentage: ' + (report.percentage?report.percentage:0)"></div>
|
|
||||||
<button *ngIf="report.percentage === 100" (click)="clear()" class="uk-icon-button uk-icon-button-xsmall uk-button-default uk-position-top-right"><icon name="close" [flex]="true" ratio="0.8"></icon></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
styleUrls: ['cache-indicators.component.less']
|
|
||||||
})
|
|
||||||
export class CacheIndicatorsComponent implements OnInit, OnChanges, OnDestroy {
|
|
||||||
report: Report;
|
|
||||||
subscriptions: Subscription[] = [];
|
|
||||||
interval: number = 10000;
|
|
||||||
readonly destroy$ = new Subject();
|
|
||||||
@Input() alias: string;
|
|
||||||
|
|
||||||
constructor(private cacheIndicatorsService: CacheIndicatorsService,
|
|
||||||
@Inject(PLATFORM_ID) private platformId) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.getReport();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges) {
|
|
||||||
if(changes.alias) {
|
|
||||||
this.getReport();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getReport() {
|
|
||||||
this.clear();
|
|
||||||
this.subscriptions.push(this.cacheIndicatorsService.getReport(this.alias).subscribe(report => {
|
|
||||||
this.getReportInterval(report);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
getReportInterval(report: Report) {
|
|
||||||
if(this.isBrowser && (this.report || !report?.completed)) {
|
|
||||||
this.report = report;
|
|
||||||
this.subscriptions.push(interval(this.interval).pipe(
|
|
||||||
map(() => this.cacheIndicatorsService.getReport(this.alias)),
|
|
||||||
switchMap(report => report),
|
|
||||||
takeUntil(this.destroy$)).subscribe(report => {
|
|
||||||
console.log(this.alias);
|
|
||||||
this.report = report;
|
|
||||||
if(this.report.completed) {
|
|
||||||
this.destroy$.next();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clear() {
|
|
||||||
this.subscriptions.forEach(subscription => {
|
|
||||||
subscription.unsubscribe();
|
|
||||||
})
|
|
||||||
this.report = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
get isBrowser() {
|
|
||||||
return this.platformId === 'browser';
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.clear();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
import {NgModule} from "@angular/core";
|
|
||||||
import {CommonModule} from "@angular/common";
|
|
||||||
import {CacheIndicatorsComponent} from "./cache-indicators.component";
|
|
||||||
import {IconsModule} from "../openaireLibrary/utils/icons/icons.module";
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [CommonModule, IconsModule],
|
|
||||||
declarations: [CacheIndicatorsComponent],
|
|
||||||
exports: [CacheIndicatorsComponent]
|
|
||||||
})
|
|
||||||
export class CacheIndicatorsModule {}
|
|
|
@ -6,7 +6,7 @@ import {Meta, Title} from "@angular/platform-browser";
|
||||||
import {SEOService} from "../openaireLibrary/sharedComponents/SEO/SEO.service";
|
import {SEOService} from "../openaireLibrary/sharedComponents/SEO/SEO.service";
|
||||||
import {properties} from "../../environments/environment";
|
import {properties} from "../../environments/environment";
|
||||||
import {Router} from "@angular/router";
|
import {Router} from "@angular/router";
|
||||||
import {StakeholderUtils} from "../utils/indicator-utils";
|
import {StakeholderUtils} from "../openaireLibrary/monitor-admin/utils/indicator-utils";
|
||||||
import {OpenaireEntities} from "../openaireLibrary/utils/properties/searchFields";
|
import {OpenaireEntities} from "../openaireLibrary/utils/properties/searchFields";
|
||||||
import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties";
|
import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties";
|
||||||
import {PiwikService} from "../openaireLibrary/utils/piwik/piwik.service";
|
import {PiwikService} from "../openaireLibrary/utils/piwik/piwik.service";
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
.uk-border-circle {
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
& > img {
|
|
||||||
max-width: 64px;
|
|
||||||
max-height: 64px;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,443 +0,0 @@
|
||||||
import {Component, Input, OnDestroy, ViewChild} from "@angular/core";
|
|
||||||
import {Stakeholder} from "../../openaireLibrary/monitor/entities/stakeholder";
|
|
||||||
import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms";
|
|
||||||
import {StakeholderUtils} from "../../utils/indicator-utils";
|
|
||||||
import {Option} from "../../openaireLibrary/sharedComponents/input/input.component";
|
|
||||||
import {Subscription} from "rxjs";
|
|
||||||
import {EnvProperties} from "../../openaireLibrary/utils/properties/env-properties";
|
|
||||||
import {properties} from "../../../environments/environment";
|
|
||||||
import {StakeholderService} from "../../openaireLibrary/monitor/services/stakeholder.service";
|
|
||||||
import {UtilitiesService} from "../../openaireLibrary/services/utilities.service";
|
|
||||||
import {Role, Session, User} from "../../openaireLibrary/login/utils/helper.class";
|
|
||||||
import {UserManagementService} from "../../openaireLibrary/services/user-management.service";
|
|
||||||
import {StringUtils} from "../../openaireLibrary/utils/string-utils.class";
|
|
||||||
import {NotifyFormComponent} from "../../openaireLibrary/notifications/notify-form/notify-form.component";
|
|
||||||
import {NotificationUtils} from "../../openaireLibrary/notifications/notification-utils";
|
|
||||||
import {Notification} from "../../openaireLibrary/notifications/notifications";
|
|
||||||
import {NotificationHandler} from "../../openaireLibrary/utils/notification-handler";
|
|
||||||
import {StatsProfilesService} from "../../utils/services/stats-profiles.service";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'edit-stakeholder',
|
|
||||||
template: `
|
|
||||||
<form *ngIf="stakeholderFb" [formGroup]="stakeholderFb">
|
|
||||||
<div class="uk-grid uk-grid-large" uk-grid>
|
|
||||||
<div class="uk-width-1-2@m">
|
|
||||||
<div input id="name" [formInput]="stakeholderFb.get('name')"
|
|
||||||
placeholder="Name"></div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-width-1-2@m">
|
|
||||||
<div input [formInput]="stakeholderFb.get('alias')"
|
|
||||||
placeholder="URL Alias"></div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-width-1-3@m">
|
|
||||||
<div input [formInput]="stakeholderFb.get('index_id')"
|
|
||||||
placeholder="Index ID"></div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-width-1-3@m">
|
|
||||||
<div input [formInput]="stakeholderFb.get('index_name')"
|
|
||||||
placeholder="Index Name"></div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-width-1-3@m">
|
|
||||||
<div input [formInput]="stakeholderFb.get('index_shortName')"
|
|
||||||
placeholder="Index Short Name"></div>
|
|
||||||
</div>
|
|
||||||
<ng-container *ngIf="isCurator">
|
|
||||||
<div class="uk-width-1-3@m">
|
|
||||||
<div *ngIf="statsProfiles" input [formInput]="stakeholderFb.get('statsProfile')" [type]="'select'"
|
|
||||||
[options]="statsProfiles"
|
|
||||||
placeholder="Stats Profile"></div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-width-1-3@m">
|
|
||||||
<div input [formInput]="stakeholderFb.get('projectUpdateDate')" [type]="'date'"
|
|
||||||
placeholder="Last Project Update"></div>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
<div class="uk-width-1-3@m">
|
|
||||||
<div input [formInput]="stakeholderFb.get('locale')" [type]="'select'"
|
|
||||||
[options]="stakeholderUtils.locales"
|
|
||||||
placeholder="Locale"></div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-width-1-1">
|
|
||||||
<div input [type]="'textarea'" placeholder="Description"
|
|
||||||
[rows]="4" [formInput]="stakeholderFb.get('description')"></div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-width-1-1">
|
|
||||||
<input #file id="photo" type="file" class="uk-hidden" (change)="fileChangeEvent($event)"/>
|
|
||||||
<div *ngIf="!stakeholderFb.get('isUpload').value" class="uk-grid uk-grid-column-large" uk-grid>
|
|
||||||
<div class="uk-margin-top uk-width-auto@l uk-width-1-1">
|
|
||||||
<div class="uk-grid uk-grid-column-large uk-flex-middle" uk-grid>
|
|
||||||
<div class="uk-width-auto@l uk-width-1-1 uk-flex uk-flex-center">
|
|
||||||
<button class="uk-button uk-button-primary uk-flex uk-flex-middle uk-flex-wrap"
|
|
||||||
(click)="file.click()">
|
|
||||||
<icon name="cloud_upload" [flex]="true"></icon>
|
|
||||||
<span class="uk-margin-small-left">Upload a file</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="uk-text-center uk-text-bold uk-width-expand">
|
|
||||||
OR
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div input class="uk-width-expand" type="logoURL" [placeholder]="'Link to the logo'"
|
|
||||||
[formInput]="stakeholderFb.get('logoUrl')"></div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="stakeholderFb.get('isUpload').value" class="uk-width-1-1 uk-flex uk-flex-middle">
|
|
||||||
<div class="uk-card uk-card-default uk-text-center uk-border-circle">
|
|
||||||
<img class="uk-position-center uk-blend-multiply" [src]="photo">
|
|
||||||
</div>
|
|
||||||
<div class="uk-margin-left">
|
|
||||||
<button (click)="remove()" class="uk-button-danger uk-icon-button uk-icon-button-small">
|
|
||||||
<icon [flex]="true" ratio="0.8" name="delete"></icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="uk-margin-small-left">
|
|
||||||
<button class="uk-button-secondary uk-icon-button uk-icon-button-small"
|
|
||||||
(click)="file.click()">
|
|
||||||
<icon [flex]="true" ratio="0.8" name="edit"></icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- Full width error message -->
|
|
||||||
<div *ngIf="uploadError" class="uk-text-danger uk-margin-small-top uk-width-1-1">{{uploadError}}</div>
|
|
||||||
</div>
|
|
||||||
<div [class]="canChooseTemplate ? 'uk-width-1-3@m' : 'uk-width-1-2@m'">
|
|
||||||
<div input [formInput]="stakeholderFb.get('visibility')"
|
|
||||||
[placeholder]="'Select a status'"
|
|
||||||
[options]="stakeholderUtils.statuses" type="select"></div>
|
|
||||||
</div>
|
|
||||||
<div [class]="canChooseTemplate ? 'uk-width-1-3@m' : 'uk-width-1-2@m'">
|
|
||||||
<div input [formInput]="stakeholderFb.get('type')"
|
|
||||||
[placeholder]="'Select a type'"
|
|
||||||
[options]="types" type="select"></div>
|
|
||||||
</div>
|
|
||||||
<ng-container *ngIf="canChooseTemplate">
|
|
||||||
<div class="uk-width-1-3@m">
|
|
||||||
<div [placeholder]="'Select a template'"
|
|
||||||
input [formInput]="stakeholderFb.get('defaultId')"
|
|
||||||
[options]="defaultStakeholdersOptions" type="select"></div>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<div #notify [class.uk-hidden]="!stakeholderFb" notify-form
|
|
||||||
class="uk-width-1-1 uk-margin-large-top uk-margin-medium-bottom"></div>
|
|
||||||
`,
|
|
||||||
styleUrls: ['edit-stakeholder.component.less']
|
|
||||||
})
|
|
||||||
export class EditStakeholderComponent implements OnDestroy {
|
|
||||||
@Input()
|
|
||||||
public disableAlias: boolean = false;
|
|
||||||
public stakeholderFb: UntypedFormGroup;
|
|
||||||
public secure: boolean = false;
|
|
||||||
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
|
|
||||||
public defaultStakeholdersOptions: Option[];
|
|
||||||
public defaultStakeholders: Stakeholder[];
|
|
||||||
public alias: string[];
|
|
||||||
public stakeholder: Stakeholder;
|
|
||||||
public isDefault: boolean;
|
|
||||||
public isNew: boolean;
|
|
||||||
public loading: boolean = false;
|
|
||||||
public types: Option[];
|
|
||||||
public statsProfiles: string[];
|
|
||||||
public properties: EnvProperties = properties;
|
|
||||||
private subscriptions: any[] = [];
|
|
||||||
/**
|
|
||||||
* Photo upload
|
|
||||||
* */
|
|
||||||
public file: File;
|
|
||||||
public photo: string | ArrayBuffer;
|
|
||||||
public uploadError: string;
|
|
||||||
public deleteCurrentPhoto: boolean = false;
|
|
||||||
private maxsize: number = 200 * 1024;
|
|
||||||
user: User;
|
|
||||||
@ViewChild('notify', {static: true}) notify: NotifyFormComponent;
|
|
||||||
private notification: Notification;
|
|
||||||
|
|
||||||
constructor(private fb: UntypedFormBuilder,
|
|
||||||
private stakeholderService: StakeholderService,
|
|
||||||
private statsProfileService: StatsProfilesService,
|
|
||||||
private utilsService: UtilitiesService, private userManagementService: UserManagementService,) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public init(stakeholder: Stakeholder, alias: string[], defaultStakeholders: Stakeholder[], isDefault: boolean, isNew: boolean) {
|
|
||||||
this.reset();
|
|
||||||
this.deleteCurrentPhoto = false;
|
|
||||||
this.stakeholder = stakeholder;
|
|
||||||
this.alias = alias;
|
|
||||||
this.defaultStakeholders = defaultStakeholders;
|
|
||||||
this.isDefault = isDefault;
|
|
||||||
this.isNew = isNew;
|
|
||||||
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
|
|
||||||
this.user = user;
|
|
||||||
if (this.isCurator) {
|
|
||||||
this.subscriptions.push(this.statsProfileService.getStatsProfiles().subscribe(statsProfiles => {
|
|
||||||
this.statsProfiles = statsProfiles;
|
|
||||||
}, error => {
|
|
||||||
this.statsProfiles = [];
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
this.statsProfiles = [];
|
|
||||||
}
|
|
||||||
this.types = this.stakeholderUtils.getTypesByUserRoles(this.user, this.stakeholder.alias);
|
|
||||||
this.stakeholderFb = this.fb.group({
|
|
||||||
_id: this.fb.control(this.stakeholder._id),
|
|
||||||
defaultId: this.fb.control(this.stakeholder.defaultId),
|
|
||||||
name: this.fb.control(this.stakeholder.name, Validators.required),
|
|
||||||
description: this.fb.control(this.stakeholder.description),
|
|
||||||
index_name: this.fb.control(this.stakeholder.index_name, Validators.required),
|
|
||||||
index_id: this.fb.control(this.stakeholder.index_id, Validators.required),
|
|
||||||
index_shortName: this.fb.control(this.stakeholder.index_shortName, Validators.required),
|
|
||||||
statsProfile: this.fb.control(this.stakeholder.statsProfile, Validators.required),
|
|
||||||
locale: this.fb.control(this.stakeholder.locale, Validators.required),
|
|
||||||
projectUpdateDate: this.fb.control(this.stakeholder.projectUpdateDate),
|
|
||||||
creationDate: this.fb.control(this.stakeholder.creationDate),
|
|
||||||
alias: this.fb.control(this.stakeholder.alias,
|
|
||||||
[
|
|
||||||
Validators.required,
|
|
||||||
this.stakeholderUtils.aliasValidatorString(
|
|
||||||
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),
|
|
||||||
topics: this.fb.control(this.stakeholder.topics),
|
|
||||||
isUpload: this.fb.control(this.stakeholder.isUpload),
|
|
||||||
logoUrl: this.fb.control(this.stakeholder.logoUrl),
|
|
||||||
});
|
|
||||||
if (this.stakeholder.isUpload) {
|
|
||||||
this.stakeholderFb.get('logoUrl').clearValidators();
|
|
||||||
this.stakeholderFb.get('logoUrl').updateValueAndValidity();
|
|
||||||
} else {
|
|
||||||
this.stakeholderFb.get('logoUrl').setValidators([StringUtils.urlValidator()]);
|
|
||||||
this.stakeholderFb.get('logoUrl').updateValueAndValidity();
|
|
||||||
}
|
|
||||||
this.subscriptions.push(this.stakeholderFb.get('isUpload').valueChanges.subscribe(value => {
|
|
||||||
if (value == true) {
|
|
||||||
this.stakeholderFb.get('logoUrl').clearValidators();
|
|
||||||
this.stakeholderFb.updateValueAndValidity();
|
|
||||||
} else {
|
|
||||||
this.stakeholderFb.get('logoUrl').setValidators([StringUtils.urlValidator()]);
|
|
||||||
this.stakeholderFb.updateValueAndValidity();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
this.secure = (!this.stakeholderFb.get('logoUrl').value || this.stakeholderFb.get('logoUrl').value.includes('https://'));
|
|
||||||
this.subscriptions.push(this.stakeholderFb.get('logoUrl').valueChanges.subscribe(value => {
|
|
||||||
this.secure = (!value || value.includes('https://'));
|
|
||||||
}));
|
|
||||||
this.initPhoto();
|
|
||||||
this.subscriptions.push(this.stakeholderFb.get('type').valueChanges.subscribe(value => {
|
|
||||||
this.onTypeChange(value, defaultStakeholders);
|
|
||||||
}));
|
|
||||||
this.stakeholderFb.setControl('defaultId', this.fb.control(stakeholder.defaultId, (this.isDefault && !this.isNew)?[]:Validators.required));
|
|
||||||
if (!this.isNew) {
|
|
||||||
this.notification = NotificationUtils.editStakeholder(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name);
|
|
||||||
this.notify.reset(this.notification.message);
|
|
||||||
if (this.isAdmin) {
|
|
||||||
if (this.disableAlias) {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.stakeholderFb.get('alias').disable();
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!this.isCurator) {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.stakeholderFb.get('statsProfile').disable();
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
this.stakeholderFb.get('alias').disable();
|
|
||||||
this.stakeholderFb.get('index_id').disable();
|
|
||||||
this.stakeholderFb.get('index_name').disable();
|
|
||||||
this.stakeholderFb.get('index_shortName').disable();
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
this.stakeholderFb.get('type').disable();
|
|
||||||
}, 0);
|
|
||||||
} else {
|
|
||||||
this.notification = NotificationUtils.createStakeholder(this.user.firstname + ' ' + this.user.lastname);
|
|
||||||
this.notify.reset(this.notification.message);
|
|
||||||
setTimeout(() => {
|
|
||||||
this.stakeholderFb.get('type').enable();
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
public get isAdmin() {
|
|
||||||
return Session.isPortalAdministrator(this.user);
|
|
||||||
}
|
|
||||||
|
|
||||||
public get isCurator() {
|
|
||||||
return this.stakeholder && (this.isAdmin || Session.isCurator(this.stakeholder.type, this.user));
|
|
||||||
}
|
|
||||||
|
|
||||||
public get disabled(): boolean {
|
|
||||||
return (this.stakeholderFb && this.stakeholderFb.invalid) ||
|
|
||||||
(this.stakeholderFb && this.stakeholderFb.pristine && !this.isNew && !this.file) ||
|
|
||||||
(this.uploadError && this.uploadError.length > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public get dirty(): boolean {
|
|
||||||
return this.stakeholderFb && this.stakeholderFb.dirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get canChooseTemplate(): boolean {
|
|
||||||
return this.isNew && this.stakeholderFb.get('type').valid && !!this.defaultStakeholdersOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
reset() {
|
|
||||||
this.uploadError = null;
|
|
||||||
this.stakeholderFb = null;
|
|
||||||
this.subscriptions.forEach(subscription => {
|
|
||||||
if (subscription instanceof Subscription) {
|
|
||||||
subscription.unsubscribe();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onTypeChange(value, defaultStakeholders: Stakeholder[]) {
|
|
||||||
this.stakeholderFb.setControl('defaultId', this.fb.control(this.stakeholder.defaultId, (this.isDefault && !this.isNew)?[]:Validators.required));
|
|
||||||
this.defaultStakeholdersOptions = [{
|
|
||||||
label: 'New blank profile',
|
|
||||||
value: '-1'
|
|
||||||
}];
|
|
||||||
defaultStakeholders.filter(stakeholder => stakeholder.type === value).forEach(stakeholder => {
|
|
||||||
this.defaultStakeholdersOptions.push({
|
|
||||||
label: 'Use ' + stakeholder.name + ' profile',
|
|
||||||
value: stakeholder._id
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public save(callback: Function, errorCallback: Function = null) {
|
|
||||||
this.loading = true;
|
|
||||||
if (this.file) {
|
|
||||||
this.subscriptions.push(this.utilsService.uploadPhoto(this.properties.utilsService + "/upload/" + encodeURIComponent(this.stakeholderFb.getRawValue().type) + "/" + encodeURIComponent(this.stakeholderFb.getRawValue().alias), this.file).subscribe(res => {
|
|
||||||
this.deletePhoto();
|
|
||||||
this.stakeholderFb.get('logoUrl').setValue(res.filename);
|
|
||||||
this.removePhoto();
|
|
||||||
this.saveStakeholder(callback, errorCallback);
|
|
||||||
}, error => {
|
|
||||||
this.uploadError = "An error has been occurred during upload your image. Try again later";
|
|
||||||
this.saveStakeholder(callback, errorCallback);
|
|
||||||
}));
|
|
||||||
} else if (this.deleteCurrentPhoto) {
|
|
||||||
this.deletePhoto();
|
|
||||||
this.saveStakeholder(callback, errorCallback);
|
|
||||||
} else {
|
|
||||||
this.saveStakeholder(callback, errorCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public saveStakeholder(callback: Function, errorCallback: Function = null) {
|
|
||||||
if (this.isNew) {
|
|
||||||
let defaultStakeholder = this.defaultStakeholders.find(value => value._id === this.stakeholderFb.getRawValue().defaultId);
|
|
||||||
this.stakeholderFb.setValue(this.stakeholderUtils.createFunderFromDefaultProfile(this.stakeholderFb.getRawValue(),
|
|
||||||
(defaultStakeholder ? defaultStakeholder.topics : []), this.stakeholderFb.getRawValue().isDefault));
|
|
||||||
this.removePhoto();
|
|
||||||
if(this.stakeholderFb.getRawValue().isDefault) {
|
|
||||||
this.stakeholderFb.get('defaultId').setValue(null);
|
|
||||||
}
|
|
||||||
this.subscriptions.push(this.stakeholderService.buildStakeholder(this.properties.monitorServiceAPIURL,
|
|
||||||
this.stakeholderFb.getRawValue()).subscribe(stakeholder => {
|
|
||||||
this.notification.entity = stakeholder._id;
|
|
||||||
this.notification.stakeholder = stakeholder.alias;
|
|
||||||
this.notification.stakeholderType = stakeholder.type;
|
|
||||||
this.notification.groups = [Role.curator(stakeholder.type)];
|
|
||||||
this.notify.sendNotification(this.notification);
|
|
||||||
NotificationHandler.rise(stakeholder.name + ' has been <b>successfully created</b>');
|
|
||||||
callback(stakeholder);
|
|
||||||
this.loading = false;
|
|
||||||
}, error => {
|
|
||||||
NotificationHandler.rise('An error has occurred. Please try again later', 'danger');
|
|
||||||
if (errorCallback) {
|
|
||||||
errorCallback(error)
|
|
||||||
}
|
|
||||||
this.loading = false;
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
this.subscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.stakeholderFb.getRawValue()).subscribe(stakeholder => {
|
|
||||||
this.notification.entity = stakeholder._id;
|
|
||||||
this.notification.stakeholder = stakeholder.alias;
|
|
||||||
this.notification.stakeholderType = stakeholder.type;
|
|
||||||
this.notification.groups = [Role.curator(stakeholder.type), Role.manager(stakeholder.type, stakeholder.alias)];
|
|
||||||
this.notify.sendNotification(this.notification);
|
|
||||||
NotificationHandler.rise(stakeholder.name + ' has been <b>successfully saved</b>');
|
|
||||||
callback(stakeholder);
|
|
||||||
this.loading = false;
|
|
||||||
}, error => {
|
|
||||||
NotificationHandler.rise('An error has occurred. Please try again later', 'danger');
|
|
||||||
if (errorCallback) {
|
|
||||||
errorCallback(error)
|
|
||||||
}
|
|
||||||
this.loading = false;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileChangeEvent(event) {
|
|
||||||
if (event.target.files && event.target.files[0]) {
|
|
||||||
this.file = event.target.files[0];
|
|
||||||
if (this.file.type !== 'image/png' && this.file.type !== 'image/jpeg') {
|
|
||||||
this.uploadError = 'You must choose a file with type: image/png or image/jpeg!';
|
|
||||||
this.stakeholderFb.get('isUpload').setValue(false);
|
|
||||||
this.stakeholderFb.get('isUpload').markAsDirty();
|
|
||||||
this.removePhoto();
|
|
||||||
} else if (this.file.size > this.maxsize) {
|
|
||||||
this.uploadError = 'File exceeds size\'s limit! Maximum resolution is 256x256 pixels.';
|
|
||||||
this.stakeholderFb.get('isUpload').setValue(false);
|
|
||||||
this.stakeholderFb.get('isUpload').markAsDirty();
|
|
||||||
this.removePhoto();
|
|
||||||
} else {
|
|
||||||
this.uploadError = null;
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.readAsDataURL(this.file);
|
|
||||||
reader.onload = () => {
|
|
||||||
this.photo = reader.result;
|
|
||||||
this.stakeholderFb.get('isUpload').setValue(true);
|
|
||||||
this.stakeholderFb.get('isUpload').markAsDirty();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initPhoto() {
|
|
||||||
if (this.stakeholderFb.getRawValue().isUpload) {
|
|
||||||
this.photo = this.properties.utilsService + "/download/" + this.stakeholderFb.get('logoUrl').value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removePhoto() {
|
|
||||||
if (this.file) {
|
|
||||||
if (typeof document != 'undefined') {
|
|
||||||
(<HTMLInputElement>document.getElementById("photo")).value = "";
|
|
||||||
}
|
|
||||||
this.initPhoto();
|
|
||||||
this.file = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
remove() {
|
|
||||||
this.stakeholderFb.get('isUpload').setValue(false);
|
|
||||||
this.stakeholderFb.get('isUpload').markAsDirty();
|
|
||||||
this.removePhoto();
|
|
||||||
this.stakeholderFb.get('logoUrl').setValue(null);
|
|
||||||
if (this.stakeholder.isUpload) {
|
|
||||||
this.deleteCurrentPhoto = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public deletePhoto() {
|
|
||||||
if (this.stakeholder.logoUrl && this.stakeholder.isUpload) {
|
|
||||||
this.subscriptions.push(this.utilsService.deletePhoto(this.properties.utilsService + '/delete/' +
|
|
||||||
encodeURIComponent(this.stakeholder.type) + "/" + encodeURIComponent(this.stakeholder.alias) + "/" + this.stakeholder.logoUrl).subscribe());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
import {NgModule} from "@angular/core";
|
|
||||||
import {EditStakeholderComponent} from "./edit-stakeholder.component";
|
|
||||||
import {CommonModule} from "@angular/common";
|
|
||||||
import {InputModule} from "../../openaireLibrary/sharedComponents/input/input.module";
|
|
||||||
import {ReactiveFormsModule} from "@angular/forms";
|
|
||||||
import {IconsModule} from "../../openaireLibrary/utils/icons/icons.module";
|
|
||||||
import {NotifyFormModule} from "../../openaireLibrary/notifications/notify-form/notify-form.module";
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [CommonModule, InputModule, ReactiveFormsModule, IconsModule, NotifyFormModule],
|
|
||||||
declarations: [EditStakeholderComponent],
|
|
||||||
exports: [EditStakeholderComponent]
|
|
||||||
})
|
|
||||||
export class EditStakeholderModule {}
|
|
|
@ -1,19 +0,0 @@
|
||||||
import {NgModule} from '@angular/core';
|
|
||||||
import {RouterModule} from '@angular/router';
|
|
||||||
import {PreviousRouteRecorder} from '../openaireLibrary/utils/piwik/previousRouteRecorder.guard';
|
|
||||||
import {GeneralComponent} from "./general.component";
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
RouterModule.forChild([
|
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
component: GeneralComponent,
|
|
||||||
canDeactivate: [PreviousRouteRecorder],
|
|
||||||
data: {hasSidebar: true}
|
|
||||||
}
|
|
||||||
])
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class GeneralRoutingModule {
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
<div page-content>
|
|
||||||
<div actions>
|
|
||||||
<sidebar-mobile-toggle class="uk-margin-top uk-hidden@m uk-display-block"></sidebar-mobile-toggle>
|
|
||||||
<div class="uk-section-xsmall uk-container uk-margin-top">
|
|
||||||
<div class="uk-flex uk-flex-center uk-flex-right@m">
|
|
||||||
<button class="uk-button uk-button-default uk-margin-right"
|
|
||||||
(click)="reset()" [class.uk-disabled]="loading || !editStakeholderComponent.dirty"
|
|
||||||
[disabled]="loading || !editStakeholderComponent.dirty">Reset
|
|
||||||
</button>
|
|
||||||
<button class="uk-button uk-button-primary" [class.uk-disabled]="loading || editStakeholderComponent.disabled"
|
|
||||||
(click)="save()" [disabled]="loading || editStakeholderComponent.disabled">Save
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div inner>
|
|
||||||
<div *ngIf="stakeholder" class="uk-container">
|
|
||||||
|
|
||||||
<div class="uk-position-relative" style="min-height: 60vh">
|
|
||||||
<div [class.uk-hidden]="loading" class="uk-section uk-section-small">
|
|
||||||
<edit-stakeholder #editStakeholderComponent [disableAlias]="true"></edit-stakeholder>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="loading" class="uk-position-center">
|
|
||||||
<loading *ngIf="loading"></loading>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,75 +0,0 @@
|
||||||
import {ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild} from "@angular/core";
|
|
||||||
import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service";
|
|
||||||
import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties";
|
|
||||||
import {Stakeholder} from "../openaireLibrary/monitor/entities/stakeholder";
|
|
||||||
import { Subscription, zip} from "rxjs";
|
|
||||||
import {EditStakeholderComponent} from "./edit-stakeholder/edit-stakeholder.component";
|
|
||||||
import {properties} from "../../environments/environment";
|
|
||||||
import {Title} from "@angular/platform-browser";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'general',
|
|
||||||
templateUrl: "./general.component.html"
|
|
||||||
})
|
|
||||||
export class GeneralComponent implements OnInit, OnDestroy {
|
|
||||||
|
|
||||||
public stakeholder: Stakeholder;
|
|
||||||
public alias: string[];
|
|
||||||
public properties: EnvProperties = properties;
|
|
||||||
public defaultStakeholders: Stakeholder[];
|
|
||||||
public loading: boolean = false;
|
|
||||||
private subscriptions: any[] = [];
|
|
||||||
@ViewChild('editStakeholderComponent') editStakeholderComponent: EditStakeholderComponent;
|
|
||||||
|
|
||||||
constructor(private stakeholderService: StakeholderService,
|
|
||||||
private cdr: ChangeDetectorRef,
|
|
||||||
private title: Title) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.loading = true;
|
|
||||||
this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
|
|
||||||
this.stakeholder = stakeholder;
|
|
||||||
this.cdr.detectChanges();
|
|
||||||
if(this.stakeholder) {
|
|
||||||
this.title.setTitle(this.stakeholder.name + " | General");
|
|
||||||
let data = zip(
|
|
||||||
this.stakeholderService.getDefaultStakeholders(this.properties.monitorServiceAPIURL),
|
|
||||||
this.stakeholderService.getAlias(this.properties.monitorServiceAPIURL)
|
|
||||||
);
|
|
||||||
this.subscriptions.push(data.subscribe(res => {
|
|
||||||
this.defaultStakeholders = res[0];
|
|
||||||
this.alias = res[1];
|
|
||||||
this.reset();
|
|
||||||
this.loading = false;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
public reset() {
|
|
||||||
this.editStakeholderComponent.init(this.stakeholder, this.alias, this.defaultStakeholders, this.stakeholder.defaultId == null, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public save() {
|
|
||||||
this.loading = true;
|
|
||||||
this.editStakeholderComponent.save((stakeholder) => {
|
|
||||||
this.stakeholder = stakeholder;
|
|
||||||
this.stakeholderService.setStakeholder(this.stakeholder);
|
|
||||||
this.reset();
|
|
||||||
this.loading = false;
|
|
||||||
}, (error) => {
|
|
||||||
console.error(error);
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.subscriptions.forEach(subscription => {
|
|
||||||
if(subscription instanceof Subscription) {
|
|
||||||
subscription.unsubscribe();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
import {NgModule} from "@angular/core";
|
|
||||||
import {GeneralComponent} from "./general.component";
|
|
||||||
import {GeneralRoutingModule} from "./general-routing.module";
|
|
||||||
import {PreviousRouteRecorder} from "../openaireLibrary/utils/piwik/previousRouteRecorder.guard";
|
|
||||||
import {CommonModule} from "@angular/common";
|
|
||||||
import {RouterModule} from "@angular/router";
|
|
||||||
import {InputModule} from "../openaireLibrary/sharedComponents/input/input.module";
|
|
||||||
import {LoadingModule} from "../openaireLibrary/utils/loading/loading.module";
|
|
||||||
import {AlertModalModule} from "../openaireLibrary/utils/modal/alertModal.module";
|
|
||||||
import {ReactiveFormsModule} from "@angular/forms";
|
|
||||||
import {EditStakeholderModule} from "./edit-stakeholder/edit-stakeholder.module";
|
|
||||||
import {PageContentModule} from "../openaireLibrary/dashboard/sharedComponents/page-content/page-content.module";
|
|
||||||
import {LogoUrlPipeModule} from "../openaireLibrary/utils/pipes/logoUrlPipe.module";
|
|
||||||
import {
|
|
||||||
SidebarMobileToggleModule
|
|
||||||
} from "../openaireLibrary/dashboard/sharedComponents/sidebar/sidebar-mobile-toggle/sidebar-mobile-toggle.module";
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [GeneralComponent],
|
|
||||||
imports: [
|
|
||||||
GeneralRoutingModule,
|
|
||||||
CommonModule,
|
|
||||||
RouterModule,
|
|
||||||
InputModule,
|
|
||||||
LoadingModule,
|
|
||||||
AlertModalModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
EditStakeholderModule,
|
|
||||||
PageContentModule,
|
|
||||||
LogoUrlPipeModule,
|
|
||||||
SidebarMobileToggleModule
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
PreviousRouteRecorder,
|
|
||||||
],
|
|
||||||
exports: [GeneralComponent]
|
|
||||||
})
|
|
||||||
export class GeneralModule {
|
|
||||||
|
|
||||||
}
|
|
|
@ -3,17 +3,17 @@ import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholde
|
||||||
import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties";
|
import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties";
|
||||||
import {Stakeholder, StakeholderEntities, Visibility} from "../openaireLibrary/monitor/entities/stakeholder";
|
import {Stakeholder, StakeholderEntities, Visibility} from "../openaireLibrary/monitor/entities/stakeholder";
|
||||||
import {Subscriber, zip} from "rxjs";
|
import {Subscriber, zip} from "rxjs";
|
||||||
import {StakeholderUtils} from "../utils/indicator-utils";
|
import {StakeholderUtils} from "../openaireLibrary/monitor-admin/utils/indicator-utils";
|
||||||
import {UntypedFormBuilder, UntypedFormGroup} from "@angular/forms";
|
import {UntypedFormBuilder, UntypedFormGroup} from "@angular/forms";
|
||||||
import {AlertModal} from "../openaireLibrary/utils/modal/alert";
|
import {AlertModal} from "../openaireLibrary/utils/modal/alert";
|
||||||
import {Option} from "../openaireLibrary/sharedComponents/input/input.component";
|
import {Option} from "../openaireLibrary/sharedComponents/input/input.component";
|
||||||
import {Title} from "@angular/platform-browser";
|
import {Title} from "@angular/platform-browser";
|
||||||
import {UserManagementService} from "../openaireLibrary/services/user-management.service";
|
import {UserManagementService} from "../openaireLibrary/services/user-management.service";
|
||||||
import {Session} from "../openaireLibrary/login/utils/helper.class";
|
import {Session} from "../openaireLibrary/login/utils/helper.class";
|
||||||
import {EditStakeholderComponent} from "../general/edit-stakeholder/edit-stakeholder.component";
|
import {EditStakeholderComponent} from "../openaireLibrary/monitor-admin/general/edit-stakeholder/edit-stakeholder.component";
|
||||||
import {properties} from "../../environments/environment";
|
import {properties} from "../../environments/environment";
|
||||||
import {ActivatedRoute} from "@angular/router";
|
import {ActivatedRoute} from "@angular/router";
|
||||||
import {CacheIndicatorsService} from "../utils/services/cache-indicators.service";
|
import {CacheIndicatorsService} from "../openaireLibrary/monitor-admin/utils/cache-indicators/cache-indicators.service";
|
||||||
import {NotificationHandler} from "../openaireLibrary/utils/notification-handler";
|
import {NotificationHandler} from "../openaireLibrary/utils/notification-handler";
|
||||||
|
|
||||||
type Tab = 'all' | 'templates'| 'profiles';
|
type Tab = 'all' | 'templates'| 'profiles';
|
||||||
|
|
|
@ -8,7 +8,6 @@ import {InputModule} from "../openaireLibrary/sharedComponents/input/input.modul
|
||||||
import {LoadingModule} from "../openaireLibrary/utils/loading/loading.module";
|
import {LoadingModule} from "../openaireLibrary/utils/loading/loading.module";
|
||||||
import {AlertModalModule} from "../openaireLibrary/utils/modal/alertModal.module";
|
import {AlertModalModule} from "../openaireLibrary/utils/modal/alertModal.module";
|
||||||
import {ReactiveFormsModule} from "@angular/forms";
|
import {ReactiveFormsModule} from "@angular/forms";
|
||||||
import {EditStakeholderModule} from "../general/edit-stakeholder/edit-stakeholder.module";
|
|
||||||
import {IconsModule} from "../openaireLibrary/utils/icons/icons.module";
|
import {IconsModule} from "../openaireLibrary/utils/icons/icons.module";
|
||||||
import {IconsService} from "../openaireLibrary/utils/icons/icons.service";
|
import {IconsService} from "../openaireLibrary/utils/icons/icons.service";
|
||||||
import {earth, incognito, restricted} from "../openaireLibrary/utils/icons/icons";
|
import {earth, incognito, restricted} from "../openaireLibrary/utils/icons/icons";
|
||||||
|
@ -19,6 +18,7 @@ import {
|
||||||
SidebarMobileToggleModule
|
SidebarMobileToggleModule
|
||||||
} from "../openaireLibrary/dashboard/sharedComponents/sidebar/sidebar-mobile-toggle/sidebar-mobile-toggle.module";
|
} from "../openaireLibrary/dashboard/sharedComponents/sidebar/sidebar-mobile-toggle/sidebar-mobile-toggle.module";
|
||||||
import {SliderTabsModule} from "../openaireLibrary/sharedComponents/tabs/slider-tabs.module";
|
import {SliderTabsModule} from "../openaireLibrary/sharedComponents/tabs/slider-tabs.module";
|
||||||
|
import {EditStakeholderModule} from "../openaireLibrary/monitor-admin/general/edit-stakeholder/edit-stakeholder.module";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [ManageStakeholdersComponent],
|
declarations: [ManageStakeholdersComponent],
|
||||||
|
|
|
@ -277,14 +277,14 @@
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="stakeholder && !privateStakeholder " href="#style_switcher" uk-toggle="" id="filters_switcher_toggle"
|
<a *ngIf="stakeholder && !privateStakeholder " href="#style_switcher" uk-toggle="" id="filters_switcher_toggle"
|
||||||
class="uk-offcanvas-switcher uk-flex uk-flex-center uk-flex-middle">
|
class="uk-offcanvas-switcher uk-flex uk-flex-center uk-flex-middle uk-link-reset">
|
||||||
<icon name="filters" ratio="1.5" visuallyHidden="Filters" gradient="filters_icon"></icon>
|
<icon name="filters" ratio="1.5" visuallyHidden="Filters" gradient="filters_icon"></icon>
|
||||||
<span [class.uk-hidden]="countSelectedFilters() === 0"
|
<span [class.uk-hidden]="countSelectedFilters() === 0"
|
||||||
class="uk-offcanvas-count uk-flex uk-flex-middle uk-flex-center">
|
class="uk-offcanvas-count uk-flex uk-flex-middle uk-flex-center">
|
||||||
{{countSelectedFilters()}}
|
{{countSelectedFilters()}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</a>
|
||||||
<div *ngIf="stakeholder && !privateStakeholder" id="style_switcher" class="uk-offcanvas"
|
<div *ngIf="stakeholder && !privateStakeholder" id="style_switcher" class="uk-offcanvas"
|
||||||
uk-offcanvas="flip:true; overlay: true">
|
uk-offcanvas="flip:true; overlay: true">
|
||||||
<div class="uk-offcanvas-bar">
|
<div class="uk-offcanvas-bar">
|
||||||
|
|
|
@ -21,8 +21,8 @@ import {
|
||||||
Topic,
|
Topic,
|
||||||
Visibility
|
Visibility
|
||||||
} from "../openaireLibrary/monitor/entities/stakeholder";
|
} from "../openaireLibrary/monitor/entities/stakeholder";
|
||||||
import {StatisticsService} from "../utils/services/statistics.service";
|
import {StatisticsService} from "../openaireLibrary/monitor-admin/utils/services/statistics.service";
|
||||||
import {IndicatorUtils} from "../utils/indicator-utils";
|
import {IndicatorUtils} from "../openaireLibrary/monitor-admin/utils/indicator-utils";
|
||||||
import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
|
import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
|
||||||
import {UntypedFormBuilder, UntypedFormControl} from "@angular/forms";
|
import {UntypedFormBuilder, UntypedFormControl} from "@angular/forms";
|
||||||
import {Subscriber, Subscription} from "rxjs";
|
import {Subscriber, Subscription} from "rxjs";
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {Schema2jsonldModule} from "../openaireLibrary/sharedComponents/schema2js
|
||||||
import {SEOServiceModule} from "../openaireLibrary/sharedComponents/SEO/SEOService.module";
|
import {SEOServiceModule} from "../openaireLibrary/sharedComponents/SEO/SEOService.module";
|
||||||
import {MonitorRoutingModule} from "./monitor-routing.module";
|
import {MonitorRoutingModule} from "./monitor-routing.module";
|
||||||
import {MonitorComponent} from "./monitor.component";
|
import {MonitorComponent} from "./monitor.component";
|
||||||
import {StatisticsService} from "../utils/services/statistics.service";
|
import {StatisticsService} from "../openaireLibrary/monitor-admin/utils/services/statistics.service";
|
||||||
import {SideBarModule} from "../openaireLibrary/dashboard/sharedComponents/sidebar/sideBar.module";
|
import {SideBarModule} from "../openaireLibrary/dashboard/sharedComponents/sidebar/sideBar.module";
|
||||||
import {InputModule} from "../openaireLibrary/sharedComponents/input/input.module";
|
import {InputModule} from "../openaireLibrary/sharedComponents/input/input.module";
|
||||||
import {UserMiniModule} from "../openaireLibrary/login/userMiniModule.module";
|
import {UserMiniModule} from "../openaireLibrary/login/userMiniModule.module";
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit c29488545e6450bd422baf158623df07b4e8cb8a
|
Subproject commit 64e8919925eb283df124fc1bcef826a5b62bf991
|
|
@ -1,490 +0,0 @@
|
||||||
<div *ngIf="stakeholder && canEdit" class="uk-section">
|
|
||||||
<div *ngIf="numberSections">
|
|
||||||
<h5 class="uk-text-bold">Number Indicators</h5>
|
|
||||||
<div class="uk-grid uk-grid-large uk-child-width-1-1" uk-grid>
|
|
||||||
<div *ngFor="let number of numbers; let i=index">
|
|
||||||
<div class="section">
|
|
||||||
<div class="tools">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<a [class.uk-disabled]="editing" class="" (click)="createSection(i, 'number')"
|
|
||||||
uk-tooltip="Create a new section">
|
|
||||||
<icon name="add" [flex]="true"></icon>
|
|
||||||
</a>
|
|
||||||
<a *ngIf="!number.defaultId" [attr.uk-tooltip]="'Delete section'"
|
|
||||||
(click)="deleteSectionOpen(number, i, 'number', 'delete')">
|
|
||||||
<icon name="close" [flex]="true"></icon>
|
|
||||||
</a>
|
|
||||||
<!-- <ng-container *ngIf="!stakeholder.defaultId">-->
|
|
||||||
<!-- <button [disabled]="editing || number.defaultId " class="md-btn md-btn-mini"-->
|
|
||||||
<!-- [title]="(number.defaultId?'Default sections cannot be deleted':'Delete all related sections')"-->
|
|
||||||
<!-- (click)="deleteSectionOpen(number, i, 'number', 'delete')"><i class="material-icons">highlight_off</i>-->
|
|
||||||
<!-- </button>-->
|
|
||||||
<!-- <button [disabled]="editing || number.defaultId " class="md-btn md-btn-mini"-->
|
|
||||||
<!-- [title]="(number.defaultId?'Default sections cannot be deleted':'Delete section and disconnect related')"-->
|
|
||||||
<!-- (click)="deleteSectionOpen(number, i, 'number', 'disconnect')"><i class="material-icons">link_off</i>-->
|
|
||||||
<!-- </button>-->
|
|
||||||
<!-- </ng-container>-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="numberSections.at(i)" class="uk-margin-medium-bottom">
|
|
||||||
<div input [formInput]="numberSections.at(i).get('title')"
|
|
||||||
(focusEmitter)="saveSection($event, numberSections.at(i), i, 'number')"
|
|
||||||
class="uk-width-1-3@m uk-width-1-1" placeholder="Title" inputClass="border-bottom"></div>
|
|
||||||
</div>
|
|
||||||
<div [id]="'number-' + number._id" class="uk-grid uk-grid-small uk-grid-match" uk-sortable="group: number" uk-grid>
|
|
||||||
<ng-template ngFor [ngForOf]="number.indicators" let-indicator let-j="index">
|
|
||||||
<div *ngIf="indicator" [id]="indicator._id"
|
|
||||||
[ngClass]="getNumberClassBySize(indicator.width)">
|
|
||||||
<div class="uk-card uk-card-default uk-padding-small number-card uk-position-relative">
|
|
||||||
<div *ngIf="!dragging"
|
|
||||||
class="uk-position-top-right uk-margin-small-right uk-margin-small-top">
|
|
||||||
<a class="uk-link-reset uk-flex uk-flex-middle" [class.uk-disabled]="editing">
|
|
||||||
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(indicator.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">
|
|
||||||
<ng-container *ngIf="isCurator">
|
|
||||||
<li><a (click)="editNumberIndicatorOpen(number, indicator._id); hide(element)">Edit</a></li>
|
|
||||||
<li class="uk-nav-divider"></li>
|
|
||||||
</ng-container>
|
|
||||||
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
|
|
||||||
<li>
|
|
||||||
<a (click)="changeIndicatorStatus(number._id, indicator, 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="indicator.visibility === v.value" [flex]="true" name="done" class="uk-text-secondary" ratio="0.8"></icon>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ng-template>
|
|
||||||
<ng-container *ngIf="!indicator.defaultId && !editing && isCurator">
|
|
||||||
<li class="uk-nav-divider">
|
|
||||||
<li><a (click)="deleteIndicatorOpen(number, indicator._id, 'number', 'delete');hide(element)">Delete</a></li>
|
|
||||||
</ng-container>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-text-small uk-text-truncate uk-margin-xsmall-bottom uk-margin-right">{{indicator.name}}</div>
|
|
||||||
<div class="number uk-text-small uk-text-bold">
|
|
||||||
<span *ngIf="numberResults.get(i + '-' + j)" [innerHTML]="(indicator.indicatorPaths[0].format == 'NUMBER'?(numberResults.get(i + '-' + j) | numberRound: 2:1:stakeholder.locale):(numberResults.get(i + '-' + j) | numberPercentage: stakeholder.locale))"></span>
|
|
||||||
<span *ngIf="!numberResults.get(i + '-' + j)">--</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="isCurator" class="uk-margin-top">
|
|
||||||
<div class="uk-grid uk-grid-small" uk-grid>
|
|
||||||
<div [ngClass]="getNumberClassBySize('small')">
|
|
||||||
<a class="uk-card uk-card-default number-card uk-padding-small uk-flex uk-flex-middle uk-link-reset" (click)="editNumberIndicatorOpen(number)">
|
|
||||||
<div class="uk-text-background uk-margin-right">
|
|
||||||
<icon name="add" [flex]="true" ratio="1.5"></icon>
|
|
||||||
</div>
|
|
||||||
<div class="uk-text-bold uk-margin-remove">
|
|
||||||
Create a number Indicator
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<ng-container *ngTemplateOutlet="new_section; context:{type: 'number'}"></ng-container>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="chartSections" class="uk-margin-large-top">
|
|
||||||
<h5 class="uk-text-bold">Chart Indicators</h5>
|
|
||||||
<div class="uk-grid uk-grid-large uk-child-width-1-1" uk-grid>
|
|
||||||
<div *ngFor="let chart of charts; let i=index">
|
|
||||||
<div class="section uk-margin-top uk-padding-small">
|
|
||||||
<div class="tools">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<a [class.uk-disabled]="editing" class="" (click)="createSection(i)"
|
|
||||||
title="Create a new section">
|
|
||||||
<icon name="add" [flex]="true"></icon>
|
|
||||||
</a>
|
|
||||||
<a *ngIf="!chart.defaultId" [attr.uk-tooltip]="'Delete section'"
|
|
||||||
(click)="deleteSectionOpen(chart, i, 'chart', 'delete')">
|
|
||||||
<icon name="close" [flex]="true"></icon>
|
|
||||||
</a>
|
|
||||||
<!-- <ng-container *ngIf="!stakeholder.defaultId">-->
|
|
||||||
<!-- <button [disabled]="editing || chart.defaultId " class="md-btn md-btn-mini"-->
|
|
||||||
<!-- [title]="(chart.defaultId?'Default sections cannot be deleted':'Delete all related sections')"-->
|
|
||||||
<!-- (click)="deleteSectionOpen(chart, i, 'chart', 'delete')"><i class="material-icons">highlight_off</i>-->
|
|
||||||
<!-- </button>-->
|
|
||||||
<!-- <button [disabled]="editing || chart.defaultId " class="md-btn md-btn-mini"-->
|
|
||||||
<!-- [title]="(chart.defaultId?'Default sections cannot be deleted':'Delete section and disconnect related')"-->
|
|
||||||
<!-- (click)="deleteSectionOpen(chart, i, 'chart', 'disconnect')"><i class="material-icons">link_off</i>-->
|
|
||||||
<!-- </button>-->
|
|
||||||
<!-- </ng-container>-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="chartSections.at(i)"
|
|
||||||
class="uk-margin-medium-bottom">
|
|
||||||
<div input [formInput]="chartSections.at(i).get('title')"
|
|
||||||
(focusEmitter)="saveSection($event, chartSections.at(i), i)"
|
|
||||||
class="uk-width-1-3@m uk-width-1-1" placeholder="Title" inputClass="border-bottom"></div>
|
|
||||||
</div>
|
|
||||||
<div [id]="'chart-' + chart._id" class="uk-grid uk-grid-small uk-grid-match" uk-sortable="group: chart" uk-grid>
|
|
||||||
<ng-template ngFor [ngForOf]="chart.indicators" let-indicator let-j="index">
|
|
||||||
<div *ngIf="indicator" [id]="indicator._id" [ngClass]="getChartClassBySize(indicator.width)">
|
|
||||||
<div class="uk-card uk-card-default uk-card-body uk-position-relative">
|
|
||||||
<div *ngIf="!dragging"
|
|
||||||
class="uk-position-top-right uk-margin-small-right uk-margin-small-top">
|
|
||||||
<a class="uk-link-reset uk-flex uk-flex-middle" [class.uk-disabled]="editing">
|
|
||||||
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(indicator.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">
|
|
||||||
<ng-container *ngIf="isCurator">
|
|
||||||
<li><a (click)="editChartIndicatorOpen(chart, indicator._id); hide(element)">Edit</a></li>
|
|
||||||
<li class="uk-nav-divider"></li>
|
|
||||||
</ng-container>
|
|
||||||
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
|
|
||||||
<li>
|
|
||||||
<a (click)="changeIndicatorStatus(chart._id, indicator, v.value);">
|
|
||||||
<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="indicator.visibility === v.value" [flex]="true" name="done" class="uk-text-secondary" ratio="0.8"></icon>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ng-template>
|
|
||||||
<ng-container *ngIf="!indicator.defaultId && !editing && isCurator">
|
|
||||||
<li class="uk-nav-divider">
|
|
||||||
<li><a (click)="deleteIndicatorOpen(chart, indicator._id, 'chart', 'delete');hide(element)">Delete</a></li>
|
|
||||||
</ng-container>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div *ngIf="indicator.name" class="uk-text-center uk-text-bold uk-margin-small-bottom">
|
|
||||||
{{indicator.name}}
|
|
||||||
</div>
|
|
||||||
<iframe *ngIf="!properties.disableFrameLoad && indicator.indicatorPaths[0] && indicator.indicatorPaths[0].source !=='image' &&
|
|
||||||
safeUrls.get(indicatorUtils.getFullUrl(stakeholder, indicator.indicatorPaths[0]))"
|
|
||||||
allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"
|
|
||||||
[src]="safeUrls.get(indicatorUtils.getFullUrl(stakeholder, indicator.indicatorPaths[0]))"
|
|
||||||
class="uk-width-1-1" [ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')"
|
|
||||||
[class.uk-blend-multiply]="!isFullscreen"></iframe>
|
|
||||||
<div *ngIf="properties.disableFrameLoad && indicator.indicatorPaths &&
|
|
||||||
indicator.indicatorPaths.length > 0 && indicator.indicatorPaths[0].source !=='image'">
|
|
||||||
<img class="uk-width-1-1 uk-blend-multiply" [ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')"
|
|
||||||
src="assets/chart-placeholder.png">
|
|
||||||
</div>
|
|
||||||
<div *ngIf="indicator.indicatorPaths && indicator.indicatorPaths[0] &&
|
|
||||||
indicator.indicatorPaths[0].source === 'image'">
|
|
||||||
<img class="uk-width-1-1 uk-blend-multiply" [ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')"
|
|
||||||
[src]="indicator.indicatorPaths[0].url">
|
|
||||||
</div>
|
|
||||||
<!--<ng-container *ngTemplateOutlet="description; context: {indicator:indicator}"></ng-container>-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="isCurator" class="uk-margin-top">
|
|
||||||
<div class="uk-grid uk-grid-small uk-grid-match" uk-grid>
|
|
||||||
<div [ngClass]="getChartClassBySize('small')">
|
|
||||||
<div class=" uk-card uk-card-default uk-card-body clickable" (click)="editChartIndicatorOpen(chart)">
|
|
||||||
<h6 class="uk-text-bold uk-text-center">
|
|
||||||
Create a custom indicator
|
|
||||||
</h6>
|
|
||||||
<div class="uk-text-muted uk-text-small">
|
|
||||||
Use our advance tool to create a custom Indicator that suit the needs of your funding
|
|
||||||
KPI's.
|
|
||||||
</div>
|
|
||||||
<div class="uk-flex uk-flex-center uk-text-background uk-margin-medium-top">
|
|
||||||
<icon name="add" ratio="3" [flex]="true"></icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<ng-container *ngTemplateOutlet="new_section; context:{type: 'chart'}"></ng-container>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<modal-alert #editNumberModal
|
|
||||||
[large]="true" classTitle="uk-background-primary uk-light"
|
|
||||||
(alertOutput)="saveIndicator()"
|
|
||||||
[okDisabled]="numberIndicatorFb && (numberIndicatorFb.invalid || numberIndicatorFb.pristine)">
|
|
||||||
<div *ngIf="editing" class="uk-position-relative uk-height-large">
|
|
||||||
<loading class="uk-position-center"></loading>
|
|
||||||
</div>
|
|
||||||
<div [class.uk-hidden]="editing" class="uk-padding-small">
|
|
||||||
<div *ngIf="numberIndicatorFb" class="uk-grid" [formGroup]="numberIndicatorFb" uk-grid>
|
|
||||||
<div input class="uk-width-1-1" [formInput]="numberIndicatorFb.get('name')" placeholder="Title"></div>
|
|
||||||
<div *ngIf="stakeholder.defaultId != '-1' && ( (indicator.description && indicator.description.length > 0) || !stakeholder.defaultId)"
|
|
||||||
input class="uk-width-1-1" [formInput]="numberIndicatorFb.get('description')" placeholder="Profile description" type="textarea">
|
|
||||||
</div>
|
|
||||||
<div input class="uk-width-1-1" *ngIf="stakeholder.defaultId" [formInput]="numberIndicatorFb.get('additionalDescription')"
|
|
||||||
placeholder="Description" type="textarea">
|
|
||||||
</div>
|
|
||||||
<div input class="uk-width-1-2@m" [formInput]="numberIndicatorFb.get('visibility')"
|
|
||||||
placeholder="Visibility" [options]="stakeholderUtils.visibility" type="select">
|
|
||||||
</div>
|
|
||||||
<div input class="uk-width-1-2@m" [formInput]="numberIndicatorFb.get('width')"
|
|
||||||
placeholder="Number Size" [options]="indicatorUtils.indicatorSizes" type="select">
|
|
||||||
</div>
|
|
||||||
<div *ngIf="numberIndicatorPaths" formArrayName="indicatorPaths">
|
|
||||||
<div *ngFor="let indicatorPath of numberIndicatorPaths.controls; let i=index" [formGroupName]="i">
|
|
||||||
<div class="uk-grid" uk-grid>
|
|
||||||
<div class="uk-width-1-1">
|
|
||||||
<div class="uk-grid" uk-grid>
|
|
||||||
<div class="uk-width-1-1 uk-flex uk-flex-middle">
|
|
||||||
<div input class="uk-width-expand" [formInput]="indicatorPath.get('url')" placeholder="Number URL">
|
|
||||||
<div *ngIf="urlParameterizedMessage" warning>{{urlParameterizedMessage}}</div>
|
|
||||||
</div>
|
|
||||||
<div class='uk-padding-small'>
|
|
||||||
<a class="uk-link-reset" (click)="copyToClipboard(indicatorPath.get('url').value)"><icon [flex]="true" name="content_copy"></icon></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="showCheckForSchemaEnhancements" class="uk-width-1-1">
|
|
||||||
<div class="uk-alert uk-alert-warning">
|
|
||||||
There are schema enhancements that can be applied in this query.<a
|
|
||||||
(click)="indicatorPath.get('url').setValue(indicatorUtils.applySchemaEnhancements(indicatorPath.get('url').value)); indicatorPath.get('url').markAsDirty()">Apply
|
|
||||||
now</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-width-1-2@m">
|
|
||||||
<div input [formInput]="indicatorPath.get('source')" placeholder="Source"
|
|
||||||
[options]="isAdministrator?indicatorUtils.allSourceTypes:indicatorUtils.sourceTypes" type="select">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-width-1-2@m">
|
|
||||||
<div input [formInput]="indicatorPath.get('format')" placeholder="Format"
|
|
||||||
[options]="indicatorUtils.formats" type="select">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div formArrayName="jsonPath" class="uk-width-1-1">
|
|
||||||
<h6 class="uk-text-bold uk-margin-remove-bottom">
|
|
||||||
<span>JSON Path</span>
|
|
||||||
</h6>
|
|
||||||
<div *ngIf="numberIndicatorPaths.at(i).get('result').invalid && numberIndicatorPaths.at(i).get('result').errors.required">
|
|
||||||
<div class="uk-text-danger uk-text-small">
|
|
||||||
This JSON path is not valid or the result has not been calculated yet.
|
|
||||||
Please press calculate on box below to see the result.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-grid uk-child-width-1-3@m uk-child-width-1-1 uk-margin-top uk-flex-middle" uk-grid>
|
|
||||||
<div *ngFor="let jsonPath of getJsonPath(i).controls; let j=index" class="uk-flex uk-flex-middle">
|
|
||||||
<div input class="uk-width-1-1" [formInput]="jsonPath" [placeholder]="'Level ' + +(j + 1)"></div>
|
|
||||||
<a [class.uk-invisible]="getJsonPath(i).length === 1 || numberIndicatorFb.get('defaultId').value"
|
|
||||||
class="uk-margin-small-left uk-text-danger"
|
|
||||||
[class.uk-disabled]="getJsonPath(i).disabled"
|
|
||||||
(click)="removeJsonPath(i, j)">
|
|
||||||
<icon name="close"></icon>
|
|
||||||
</a>
|
|
||||||
<span [class.uk-invisible]="getJsonPath(i).disabled || j === (getJsonPath(i).controls.length - 1)" class="uk-text-center uk-margin-small-left">
|
|
||||||
<icon name="east"></icon>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="indicator.defaultId === null">
|
|
||||||
<button class="uk-icon-button uk-button-primary" (click)="addJsonPath(i)">
|
|
||||||
<icon name="add" [flex]="true"></icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-width-1-1 uk-flex uk-flex-center">
|
|
||||||
<div class="uk-flex uk-position-relative">
|
|
||||||
<span class="uk-padding number number-preview uk-flex uk-flex-column uk-flex-center uk-text-center">
|
|
||||||
<span *ngIf="numberIndicatorPaths.at(i).get('result').valid && numberIndicatorPaths.at(i).get('result').value !== 0"
|
|
||||||
[innerHTML]="(numberIndicatorPaths.at(i).get('format').value == 'NUMBER'?(numberIndicatorPaths.at(i).get('result').value | numberRound: 2:1:stakeholder.locale):(numberIndicatorPaths.at(i).get('result').value | numberPercentage: stakeholder.locale))">
|
|
||||||
</span>
|
|
||||||
<span *ngIf="numberIndicatorPaths.at(i).get('result').valid && numberIndicatorPaths.at(i).get('result').value === 0">
|
|
||||||
--
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
<div *ngIf="numberIndicatorPaths.at(i).get('result').invalid"
|
|
||||||
class="uk-width-1-1 uk-height-1-1 refresh-indicator">
|
|
||||||
<div class="uk-position-relative uk-height-1-1">
|
|
||||||
<a class="uk-position-center uk-text-center uk-text-small uk-link-reset"
|
|
||||||
[class.uk-disabled]="numberIndicatorPaths.at(i).get('url').invalid"
|
|
||||||
(click)="validateJsonPath(i, true)">
|
|
||||||
<div>
|
|
||||||
<icon name="refresh"></icon>
|
|
||||||
</div>
|
|
||||||
<span *ngIf="numberIndicatorPaths.at(i).get('result').errors.required">Calculate</span>
|
|
||||||
<span *ngIf="numberIndicatorPaths.at(i).get('result').errors.validating">Calculating...</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div #editNumberNotify notify-form class="uk-width-1-1 uk-margin-medium-top"></div>
|
|
||||||
</div>
|
|
||||||
</modal-alert>
|
|
||||||
<modal-alert #editChartModal [large]="true" (alertOutput)="saveIndicator()" classTitle="uk-background-primary uk-light"
|
|
||||||
[okDisabled]="chartIndicatorFb && (chartIndicatorFb.invalid || chartIndicatorFb.pristine)">
|
|
||||||
<div *ngIf="editing" class="uk-position-relative uk-height-large">
|
|
||||||
<loading class="uk-position-center"></loading>
|
|
||||||
</div>
|
|
||||||
<div [class.uk-hidden]="editing" class="uk-padding-small">
|
|
||||||
<div *ngIf="chartIndicatorFb" [formGroup]="chartIndicatorFb" class="uk-grid" uk-grid>
|
|
||||||
<div input class="uk-width-1-1" [formInput]="chartIndicatorFb.get('name')" placeholder="Title"></div>
|
|
||||||
<div *ngIf="stakeholder.defaultId != '-1' && ((indicator.description && indicator.description.length > 0) || !stakeholder.defaultId)"
|
|
||||||
input class="uk-width-1-1" [formInput]="chartIndicatorFb.get('description')" placeholder="Default Description" type="textarea">
|
|
||||||
</div>
|
|
||||||
<div *ngIf="stakeholder.defaultId" input class="uk-width-1-1" [formInput]="chartIndicatorFb.get('additionalDescription')"
|
|
||||||
placeholder="Description" type="textarea">
|
|
||||||
</div>
|
|
||||||
<div input class="uk-width-1-2@m" [formInput]="chartIndicatorFb.get('visibility')"
|
|
||||||
placeholder="Status" [options]="stakeholderUtils.visibility" type="select">
|
|
||||||
</div>
|
|
||||||
<div input class="uk-width-1-2@m" [formInput]="chartIndicatorFb.get('width')" placeholder="Chart width"
|
|
||||||
[options]="indicatorUtils.indicatorSizes" type="select">
|
|
||||||
</div>
|
|
||||||
<div input class="uk-width-1-2@m" [formInput]="chartIndicatorFb.get('height')" placeholder="Chart height"
|
|
||||||
[options]="indicatorUtils.indicatorSizes" type="select">
|
|
||||||
</div>
|
|
||||||
<div *ngIf="chartIndicatorPaths" formArrayName="indicatorPaths" class="uk-width-1-1">
|
|
||||||
<div *ngFor="let indicatorPath of chartIndicatorPaths.controls; let i=index;"
|
|
||||||
[formGroupName]="i" class="uk-grid" uk-grid>
|
|
||||||
<div class="uk-width-1-1 uk-flex uk-flex-middle">
|
|
||||||
<div input class="uk-width-expand" [title]="indicatorPath.get('url').disabled?'Default chart URLs cannot change':''"
|
|
||||||
[formInput]="indicatorPath.get('url')" placeholder="Chart URL">
|
|
||||||
<div *ngIf="urlParameterizedMessage" warning>{{urlParameterizedMessage}}</div>
|
|
||||||
</div>
|
|
||||||
<div class='uk-padding-small'>
|
|
||||||
<a class="uk-link-reset" (click)="copyToClipboard(indicatorPath.get('url').value)"><icon [flex]="true" name="content_copy"></icon></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="showCheckForSchemaEnhancements" class=" uk-width-1-1 ">
|
|
||||||
<div class="uk-alert uk-alert-warning">
|
|
||||||
There are schema enhancements that can be applied in this query. <a
|
|
||||||
(click)="indicatorPath.get('url').setValue(indicatorUtils.applySchemaEnhancements(indicatorPath.get('url').value)); indicatorPath.get('url').markAsDirty()">Apply
|
|
||||||
now</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="uk-width-1-1" formArrayName="parameters">
|
|
||||||
<div class="uk-grid" uk-grid>
|
|
||||||
<div *ngIf="getParameter(i, 'title')" input class="uk-width-1-1" [formInput]="getParameter(i, 'title').get('value')"
|
|
||||||
placeholder="Chart Title"></div>
|
|
||||||
<div *ngIf="getParameter(i, 'subtitle')" input class="uk-width-1-1" placeholder="Chart Subtitle" [formInput]="getParameter(i, 'subtitle').get('value')" label="Chart Subtitle"></div>
|
|
||||||
<div *ngIf="!getParameter(i, 'type')" input class="uk-width-1-3@s" [formInput]="indicatorPath.get('type')" placeholder="Chart Type"
|
|
||||||
[options]="(indicatorPath.get('type').value == 'table' && getParameter(i, 'data_title_0'))?indicatorUtils.getChartTypes(indicatorPath.get('type').value):indicatorUtils.allChartTypes"
|
|
||||||
type="select"></div>
|
|
||||||
<div *ngIf="getParameter(i, 'type')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'type').get('value')" placeholder="Chart Type"
|
|
||||||
[options]="indicatorUtils.getChartTypes(getParameter(i, 'type').get('value').value)" type="select"></div>
|
|
||||||
<div *ngIf="getParameter(i, 'xAxisTitle')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'xAxisTitle').get('value')"
|
|
||||||
placeholder="X-Axis Title"></div>
|
|
||||||
<div *ngIf="getParameter(i, 'yAxisTitle')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'yAxisTitle').get('value')"
|
|
||||||
placeholder="Y-Axis Title"></div>
|
|
||||||
<div *ngIf="getParameter(i, 'data_title_0')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'data_title_0').get('value')"
|
|
||||||
placeholder="Data Title"></div>
|
|
||||||
<div *ngIf="getParameter(i, 'data_title_1')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'data_title_1').get('value')"
|
|
||||||
placeholder="Data Title"></div>
|
|
||||||
<div *ngIf="getParameter(i, 'start_year')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'start_year').get('value')"
|
|
||||||
placeholder="Year (From)"></div>
|
|
||||||
<div *ngIf="getParameter(i, 'end_year')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'end_year').get('value')"
|
|
||||||
placeholder="Year (To)"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="indicator && indicator.indicatorPaths[i] && indicator.indicatorPaths[i].safeResourceUrl"
|
|
||||||
class="uk-margin-medium-top uk-position-relative uk-width-1-1 uk-flex uk-flex-center">
|
|
||||||
<div *ngIf="(hasDifference(i)) && !indicatorPath.invalid"
|
|
||||||
class="uk-width-1-1 uk-height-large refresh-indicator">
|
|
||||||
<div class="uk-position-relative uk-height-1-1">
|
|
||||||
<a class="uk-position-center uk-text-center uk-link-reset" (click)="refreshIndicator()">
|
|
||||||
<div>
|
|
||||||
<icon name="refresh"></icon>
|
|
||||||
</div>
|
|
||||||
<span>Click to refresh the graph view</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<iframe *ngIf="indicator.indicatorPaths[i].source !== 'image'" [class.uk-blend-multiply]="!isFullscreen"
|
|
||||||
[src]="indicator.indicatorPaths[i].safeResourceUrl" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"
|
|
||||||
class="uk-width-1-1 uk-height-large"></iframe>
|
|
||||||
<!-- <div *ngIf="properties.disableFrameLoad && indicator.indicatorPaths[i].source !== 'image'" class="uk-alert uk-alert-danger uk-text-center">I frames-->
|
|
||||||
<!-- preview is disabled</div>-->
|
|
||||||
<div *ngIf="indicator.indicatorPaths[i].source === 'image'">
|
|
||||||
<img class="uk-width-1-1 uk-height-large uk-blend-multiply" [src]="indicator.indicatorPaths[i].url">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div #editChartNotify notify-form class="uk-width-1-1 uk-margin-medium-top"></div>
|
|
||||||
</div>
|
|
||||||
</modal-alert>
|
|
||||||
<modal-alert #deleteModal (alertOutput)="deleteIndicator()" [overflowBody]="false" classTitle="uk-background-primary uk-light">
|
|
||||||
<div [class.uk-invisible]="editing" class="uk-position-relative">
|
|
||||||
<div *ngIf="editing">
|
|
||||||
<loading class="uk-position-center"></loading>
|
|
||||||
</div>
|
|
||||||
You are about to delete <span class="uk-text-bold" *ngIf="indicator && index !== -1">
|
|
||||||
"{{indicator.name ? indicator.name : (indicator.indicatorPaths[0]?.parameters?.title?indicator.indicatorPaths[0].parameters.title:'')}}"</span> indicator permanently.
|
|
||||||
<div *ngIf="indicatorChildrenActionOnDelete == 'delete'" class="uk-text-bold">
|
|
||||||
Indicators of all profiles based on this default indicator, will be deleted as well.
|
|
||||||
</div>
|
|
||||||
<!-- <span *ngIf="indicatorChildrenActionOnDelete == 'disconnect'" class="uk-text-bold">-->
|
|
||||||
<!-- Indicators of all profiles based on this default indicator, will not be marked as copied from default anymore.-->
|
|
||||||
<!-- </span>-->
|
|
||||||
Are you sure you want to proceed?
|
|
||||||
<div #deleteNotify notify-form class="uk-width-1-1 uk-margin-medium-top"></div>
|
|
||||||
</div>
|
|
||||||
</modal-alert>
|
|
||||||
<!--<modal-alert #deleteAllModal (alertOutput)="deleteIndicator('delete')">
|
|
||||||
You are about to delete <span class="uk-text-bold" *ngIf="indicator && index !== -1">
|
|
||||||
"{{indicator.name ? indicator.name : indicator.indicatorPaths[0].parameters.title}}"</span> indicator permanently.
|
|
||||||
<span class="uk-text-bold">Indicators of all profiles based on this default indicator, will be deleted as well.</span>
|
|
||||||
Are you sure you want to proceed?
|
|
||||||
</modal-alert>
|
|
||||||
<modal-alert #deleteAndDisconnectModal (alertOutput)="deleteIndicator('disconnect')">
|
|
||||||
You are about to delete <span class="uk-text-bold" *ngIf="indicator && index !== -1">
|
|
||||||
"{{indicator.name ? indicator.name : indicator.indicatorPaths[0].parameters.title}}"</span> indicator permanently.
|
|
||||||
<span class="uk-text-bold">Indicators of all profiles based on this default indicator, will not be marked as copied from default anymore.</span>
|
|
||||||
Are you sure you want to proceed?
|
|
||||||
</modal-alert>-->
|
|
||||||
<modal-alert #deleteSectionModal (alertOutput)="deleteSection()" [overflowBody]="false" classTitle="uk-background-primary uk-light">
|
|
||||||
<div [class.uk-invisible]="editing" class="uk-position-relative">
|
|
||||||
<div *ngIf="editing">
|
|
||||||
<loading class="uk-position-center"></loading>
|
|
||||||
</div>
|
|
||||||
You are about to delete this section and its indicators permanently.
|
|
||||||
<div *ngIf="sectionChildrenActionOnDelete == 'delete' && !stakeholder.defaultId" class="uk-text-bold">
|
|
||||||
Sections of all profiles based on this default section and their contents, will be deleted as well.
|
|
||||||
</div>
|
|
||||||
<!-- <span *ngIf="sectionChildrenActionOnDelete == 'disconnect'" class="uk-text-bold">-->
|
|
||||||
<!-- Sections of all profiles based on this default section and their contents, will not be marked as copied from default anymore.-->
|
|
||||||
<!-- </span>-->
|
|
||||||
Are you sure you want to proceed?
|
|
||||||
</div>
|
|
||||||
</modal-alert>
|
|
||||||
<!--<modal-alert #deleteNumberSectionModal (alertOutput)="deleteSection('number')">
|
|
||||||
You are about to delete this section and its indicators permanently.
|
|
||||||
Are you sure you want to proceed?
|
|
||||||
</modal-alert>
|
|
||||||
<modal-alert #deleteChartSectionModal (alertOutput)="deleteSection()">
|
|
||||||
You are about to delete this section and its indicators permanently.
|
|
||||||
Are you sure you want to proceed?
|
|
||||||
</modal-alert>-->
|
|
||||||
<ng-template #new_section let-type="type">
|
|
||||||
<div class="section">
|
|
||||||
<div class="uk-flex uk-flex-center" (click)="createSection(-1, type)">
|
|
||||||
<button class="uk-button uk-button-primary uk-flex uk-flex-middle">
|
|
||||||
<icon name="add" [flex]="true"></icon>
|
|
||||||
<span class="uk-margin-small-left">New section</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
|
@ -1,53 +0,0 @@
|
||||||
@import (reference) "~src/assets/openaire-theme/less/_import-variables";
|
|
||||||
|
|
||||||
.number-preview {
|
|
||||||
border: @global-border-width solid @global-border;
|
|
||||||
background: transparent;
|
|
||||||
border-radius: @global-border-radius;
|
|
||||||
min-width: 100px;
|
|
||||||
min-height: 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.refresh-indicator {
|
|
||||||
background-color: @global-overlay-background;
|
|
||||||
border-radius: @global-border-radius;
|
|
||||||
position: absolute;
|
|
||||||
color: @global-inverse-color;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section {
|
|
||||||
padding: 60px 45px;
|
|
||||||
border-radius: @global-border-radius;
|
|
||||||
border: @global-border-width solid @global-border;
|
|
||||||
position: relative;
|
|
||||||
background: @global-inverse-color;
|
|
||||||
border-left: 5px @global-primary-background solid;
|
|
||||||
|
|
||||||
.tools {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -100%);
|
|
||||||
max-width: 50px;
|
|
||||||
padding: 5px 10px;
|
|
||||||
background-image: @global-primary-gradient;
|
|
||||||
color: @global-inverse-color;
|
|
||||||
-webkit-clip-path: polygon(20% 5%, 80% 5%, 100% 100%, 0% 100%);
|
|
||||||
clip-path: polygon(20% 5%, 80% 5%, 100% 100%, 0% 100%);
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.tools {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: currentColor;
|
|
||||||
&:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,19 +0,0 @@
|
||||||
import {NgModule} from '@angular/core';
|
|
||||||
import {RouterModule} from '@angular/router';
|
|
||||||
import {PreviousRouteRecorder} from '../openaireLibrary/utils/piwik/previousRouteRecorder.guard';
|
|
||||||
import {TopicComponent} from "./topic.component";
|
|
||||||
import {CanExitGuard} from "../openaireLibrary/utils/can-exit.guard";
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
RouterModule.forChild([
|
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
component: TopicComponent,
|
|
||||||
canDeactivate: [PreviousRouteRecorder, CanExitGuard]
|
|
||||||
}
|
|
||||||
])
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class TopicRoutingModule {
|
|
||||||
}
|
|
|
@ -1,379 +0,0 @@
|
||||||
<aside *ngIf="stakeholder" id="sidebar_main">
|
|
||||||
<div sidebar-content>
|
|
||||||
<div class="back">
|
|
||||||
<a [routerLink]="'/admin/' + stakeholder.alias" class="uk-flex uk-flex-middle uk-flex-center">
|
|
||||||
<div class="uk-width-auto">
|
|
||||||
<icon name="west" [flex]="true" ratio="1.3"></icon>
|
|
||||||
</div>
|
|
||||||
<span class="uk-width-expand uk-text-truncate uk-margin-left hide-on-close">Indicators</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="menu_section uk-margin-large-top">
|
|
||||||
<ul class="uk-list uk-nav uk-nav-default uk-nav-parent-icon" transition-group [id]="'topics'"
|
|
||||||
uk-nav="duration: 400">
|
|
||||||
<li *ngFor="let topic of stakeholder.topics; let i=index" class="uk-parent" [class.uk-active]="topicIndex === i"
|
|
||||||
transition-group-item>
|
|
||||||
<a [routerLink]="'/admin/'+stakeholder.alias + '/indicators/' + topic.alias"
|
|
||||||
[title]="topic.name" class="uk-visible-toggle uk-flex uk-flex-middle">
|
|
||||||
<div *ngIf="topic.icon" class="uk-width-auto">
|
|
||||||
<icon class="menu-icon" [svg]="topic.icon" ratio="0.9" [flex]="true"></icon>
|
|
||||||
</div>
|
|
||||||
<span [class.hide-on-close]="topic.icon"
|
|
||||||
class="uk-width-expand uk-text-truncate uk-margin-small-left">
|
|
||||||
{{topic.name}}
|
|
||||||
</span>
|
|
||||||
<span class="uk-margin-xsmall-left hide-on-close" [class.uk-invisible-hover]="topicIndex !== i"
|
|
||||||
(click)="$event.stopPropagation();$event.preventDefault()">
|
|
||||||
<a class="uk-link-reset uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(topic.visibility)"
|
|
||||||
ratio="0.6"></icon>
|
|
||||||
<icon [flex]="true" name="more_vert"></icon>
|
|
||||||
</a>
|
|
||||||
<div #element
|
|
||||||
uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false; container: body">
|
|
||||||
<ul class="uk-nav uk-dropdown-nav">
|
|
||||||
<ng-container *ngIf="isCurator">
|
|
||||||
<li>
|
|
||||||
<a (click)="editTopicOpen(i); hide(element)">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" name="edit" ratio="0.6"></icon>
|
|
||||||
<span class="uk-margin-small-left uk-width-expand">Edit</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li *ngIf="i > 0 || i < stakeholder.topics.length - 1" class="uk-nav-divider"></li>
|
|
||||||
<li *ngIf="i > 0">
|
|
||||||
<a (click)="hide(element);moveTopic(i)">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" name="north" ratio="0.6"></icon>
|
|
||||||
<span class="uk-margin-small-left uk-width-expand">Move Up</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li *ngIf="i < stakeholder.topics.length - 1">
|
|
||||||
<a (click)="hide(element);moveTopic(i, i + 1)">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" name="south" ratio="0.6"></icon>
|
|
||||||
<span class="uk-margin-small-left uk-width-expand">Move Down</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="uk-nav-divider"></li>
|
|
||||||
</ng-container>
|
|
||||||
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
|
|
||||||
<li [class.uk-active]="topic.visibility === v.value">
|
|
||||||
<a (click)="openVisibilityModal(i, v.value, 'topic'); 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="topic.visibility === v.value" [flex]="true" name="done"
|
|
||||||
class="uk-text-secondary" ratio="0.8"></icon>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ng-template>
|
|
||||||
<ng-container *ngIf="!topic.defaultId && isCurator">
|
|
||||||
<li class="uk-nav-divider">
|
|
||||||
<li>
|
|
||||||
<a (click)="deleteTopicOpen(i, 'delete'); 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">Delete</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<!--<ng-container *ngIf="!stakeholder.defaultId">
|
|
||||||
<a (click)="deleteTopicOpen(i, 'delete'); hide(element)">Delete from all profiles</a>
|
|
||||||
<a (click)="deleteTopicOpen(i, 'disconnect'); hide(element)">Delete and disconnect from all profiles</a>
|
|
||||||
</ng-container>-->
|
|
||||||
</li>
|
|
||||||
</ng-container>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
<ul *ngIf="isBrowser || topicIndex === i" class="uk-nav-sub" [id]="'categories-' + i.toString()"
|
|
||||||
transition-group>
|
|
||||||
<li *ngFor="let category of topic.categories; let j=index" transition-group-item class="uk-visible-toggle"
|
|
||||||
[class.uk-active]="categoryIndex == j">
|
|
||||||
<a (click)="chooseCategory(j)" [title]="category.name">
|
|
||||||
<div class="uk-flex uk-flex-middle uk-width-1-1">
|
|
||||||
<span class="uk-width-expand uk-text-truncate">{{category.name}}</span>
|
|
||||||
<span class="uk-margin-xsmall-left hide-on-close" [class.uk-invisible-hover]="categoryIndex !== j"
|
|
||||||
(click)="$event.stopPropagation();$event.preventDefault()">
|
|
||||||
<a class="uk-link-reset uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(category.visibility)"
|
|
||||||
ratio="0.6"></icon>
|
|
||||||
<icon [flex]="true" name="more_vert"></icon>
|
|
||||||
</a>
|
|
||||||
<div #element
|
|
||||||
uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false; container: body">
|
|
||||||
<ul class="uk-nav uk-dropdown-nav">
|
|
||||||
<ng-container *ngIf="isCurator">
|
|
||||||
<li>
|
|
||||||
<a (click)="editCategoryOpen(j); hide(element)">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" name="edit" ratio="0.6"></icon>
|
|
||||||
<span class="uk-margin-small-left uk-width-expand">Edit</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li *ngIf="j > 0 || j < stakeholder.topics[topicIndex].categories.length - 1"
|
|
||||||
class="uk-nav-divider"></li>
|
|
||||||
<li *ngIf="j > 0">
|
|
||||||
<a (click)="hide(element);moveCategory(j)">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" name="north" ratio="0.6"></icon>
|
|
||||||
<span class="uk-margin-small-left uk-width-expand">Move Up</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li *ngIf="j < stakeholder.topics[topicIndex].categories.length - 1">
|
|
||||||
<a (click)="hide(element);moveCategory(j, j + 1)">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" name="south" ratio="0.6"></icon>
|
|
||||||
<span class="uk-margin-small-left uk-width-expand">Move Down</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="uk-nav-divider"></li>
|
|
||||||
</ng-container>
|
|
||||||
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
|
|
||||||
<li [class.uk-active]="category.visibility === v.value">
|
|
||||||
<a (click)="openVisibilityModal(j, v.value, 'category'); 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="category.visibility === v.value" [flex]="true" name="done"
|
|
||||||
class="uk-text-secondary" ratio="0.8"></icon>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ng-template>
|
|
||||||
<ng-container *ngIf="!category.defaultId && isCurator">
|
|
||||||
<li class="uk-nav-divider">
|
|
||||||
<li>
|
|
||||||
<a (click)="deleteCategoryOpen(j, 'delete'); 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">Delete</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ng-container>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li *ngIf="isCurator">
|
|
||||||
<a (click)="editCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle">
|
|
||||||
<icon name="add" [flex]="true"></icon>
|
|
||||||
<span class="hide-on-close">Create new category</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li *ngIf="isCurator" class="hide-on-close">
|
|
||||||
<a (click)="editTopicOpen(-1); $event.preventDefault()">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<div class="uk-width-auto">
|
|
||||||
<icon class="menu-icon" name="add" [flex]="true"></icon>
|
|
||||||
</div>
|
|
||||||
<span class="uk-width-expand uk-text-truncate uk-margin-small-left hide-on-close">Create new topic</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
<div #pageContent *ngIf="stakeholder && filters" page-content>
|
|
||||||
<div actions>
|
|
||||||
<div *ngIf="stakeholder.topics.length > 0" class="uk-flex uk-flex-center uk-margin-medium-top uk-flex-right@m uk-width-1-1">
|
|
||||||
<button class="uk-button uk-button-primary uk-flex uk-flex-middle">
|
|
||||||
<icon name="visibility" [flex]="true"></icon>
|
|
||||||
<span class="uk-margin-small-left uk-margin-small-right">Preview</span>
|
|
||||||
<icon name="expand_more" [flex]="true"></icon>
|
|
||||||
</button>
|
|
||||||
<div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false">
|
|
||||||
<ul class="uk-nav uk-dropdown-nav">
|
|
||||||
<li><a target="_blank"
|
|
||||||
[routerLink]="'/' + stakeholder.alias + '/' + stakeholder.topics[topicIndex].alias"
|
|
||||||
[queryParams]="{view: 'PUBLIC'}"
|
|
||||||
(click)="hide(element)">Public view</a>
|
|
||||||
</li>
|
|
||||||
<li><a target="_blank" [routerLink]="'/' + stakeholder.alias + '/' +
|
|
||||||
stakeholder.topics[topicIndex].alias"
|
|
||||||
[queryParams]="{view: 'RESTRICTED'}"
|
|
||||||
(click)="hide(element)">Restricted view</a>
|
|
||||||
</li>
|
|
||||||
<!--<li class="disabled"><a class="uk-disabled uk-text-muted"
|
|
||||||
uk-tooltip="Note: available only in administration dashboard"
|
|
||||||
(click)="hide(element)">Private view</a>
|
|
||||||
</li>-->
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</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">
|
|
||||||
<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>
|
|
||||||
</a>
|
|
||||||
<span class="uk-flex uk-flex-column uk-flex-center uk-margin-small-left"
|
|
||||||
[class.uk-invisible-hover]="subCategoryIndex !== i"
|
|
||||||
(click)="$event.stopPropagation();$event.preventDefault()">
|
|
||||||
<a class="uk-link-reset uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(subCategory.visibility)"
|
|
||||||
ratio="0.6"></icon>
|
|
||||||
<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">
|
|
||||||
<ng-container *ngIf="isCurator">
|
|
||||||
<li>
|
|
||||||
<a (click)="editSubCategoryOpen(i); hide(element)">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" name="edit" ratio="0.6"></icon>
|
|
||||||
<span class="uk-margin-small-left uk-width-expand">Edit</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li *ngIf="i > 0 || i < stakeholder.topics[topicIndex].categories[categoryIndex].subCategories.length - 1"
|
|
||||||
class="uk-nav-divider"></li>
|
|
||||||
<li *ngIf="i > 0">
|
|
||||||
<a (click)="hide(element);moveSubCategory(i)">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" name="west" ratio="0.6"></icon>
|
|
||||||
<span class="uk-margin-small-left uk-width-expand">Move Left</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li *ngIf="i < stakeholder.topics[topicIndex].categories[categoryIndex].subCategories.length - 1">
|
|
||||||
<a (click)="hide(element);moveSubCategory(i, i + 1)">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" name="east" ratio="0.6"></icon>
|
|
||||||
<span class="uk-margin-small-left uk-width-expand">Move Right</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="uk-nav-divider"></li>
|
|
||||||
<li *ngIf="indicators">
|
|
||||||
<a (click)=" indicators.exportIndicators(i);hide(element)">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" name="download" ratio="0.6"></icon>
|
|
||||||
<span class="uk-margin-small-left uk-width-expand">Export indicators</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li *ngIf="indicators">
|
|
||||||
<a (click)="file.value = ''; this.index=i; file.click(); hide(element)">
|
|
||||||
<div class="uk-flex uk-flex-middle">
|
|
||||||
<icon [flex]="true" name="upload" ratio="0.6"></icon>
|
|
||||||
<span class="uk-margin-small-left uk-width-expand">Import indicators</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="uk-nav-divider"></li>
|
|
||||||
</ng-container>
|
|
||||||
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
|
|
||||||
<li [class.uk-active]="subCategory.visibility === v.value">
|
|
||||||
<a (click)="openVisibilityModal(i, v.value, 'subcategory'); 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="subCategory.visibility === v.value" [flex]="true" name="done"
|
|
||||||
class="uk-text-secondary" ratio="0.8"></icon>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ng-template>
|
|
||||||
<ng-container *ngIf="!subCategory.defaultId && isCurator">
|
|
||||||
<li class="uk-nav-divider">
|
|
||||||
<li>
|
|
||||||
<a (click)="deleteSubcategoryOpen(i, 'delete'); 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">Delete</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ng-container>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ng-template>
|
|
||||||
<li *ngIf="isCurator">
|
|
||||||
<a (click)="editSubCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle">
|
|
||||||
<icon name="add" [flex]="true"></icon>
|
|
||||||
<span class="uk-text-uppercase">Create new subcategory</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div inner>
|
|
||||||
<input #file id="import-file" type="file" class="uk-hidden"
|
|
||||||
(change)="indicators.fileChangeEvent($event, this.index)"/>
|
|
||||||
<indicators #indicators [topicIndex]="topicIndex" [categoryIndex]="categoryIndex"
|
|
||||||
[subcategoryIndex]="subCategoryIndex" [user]="user"
|
|
||||||
[stakeholder]="stakeholder" [changed]="change.asObservable()"></indicators>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<modal-alert #deleteModal classTitle="uk-background-primary uk-light" (alertOutput)="deleteElement()"
|
|
||||||
[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 delete <span class="uk-text-bold" *ngIf="element">"{{element.name}}"</span> {{type}} permanently.
|
|
||||||
<div *ngIf="elementChildrenActionOnDelete == 'delete'" class="uk-text-bold">
|
|
||||||
{{getPluralTypeName()}} of all profiles based on this default {{type}}, will be deleted as well.
|
|
||||||
</div>
|
|
||||||
Are you sure you want to proceed?
|
|
||||||
</div>
|
|
||||||
</modal-alert>
|
|
||||||
<modal-alert #editModal classTitle="uk-background-primary uk-light" (alertOutput)="saveElement()"
|
|
||||||
[okDisabled]="form && (form.invalid || form.pristine)" [large]="true">
|
|
||||||
<div *ngIf="loading" class="uk-position-relative uk-height-large">
|
|
||||||
<loading class="uk-position-center"></loading>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="form" [class.uk-hidden]="loading"
|
|
||||||
class="uk-grid uk-padding uk-padding-remove-horizontal uk-child-width-1-1" [formGroup]="form" uk-grid>
|
|
||||||
<div input [formInput]="form.get('name')" class="uk-width-1-2@m" placeholder="Title"></div>
|
|
||||||
<div input [formInput]="form.get('visibility')" class="uk-width-1-2@m" placeholder="Status"
|
|
||||||
[options]="stakeholderUtils.visibility" type="select"></div>
|
|
||||||
<div input [formInput]="form.get('description')" placeholder="Description" type="textarea" rows="4"></div>
|
|
||||||
<div *ngIf="form.get('icon')" input [formInput]="form.get('icon')" placeholder="Icon(SVG)" type="textarea"></div>
|
|
||||||
</div>
|
|
||||||
</modal-alert>
|
|
||||||
<modal-alert #visibilityModal [large]="false" classTitle="uk-background-primary uk-light">
|
|
||||||
<div class="">
|
|
||||||
You have the option to change the visibility status of your {{type}}, with or without applying the changed status to
|
|
||||||
its contents.
|
|
||||||
</div>
|
|
||||||
<div class="uk-flex uk-flex-center uk-margin-medium-top uk-margin-medium-bottom">
|
|
||||||
<button class="uk-button uk-button-primary" (click)="changeElementStatus()">
|
|
||||||
Change {{type}} status
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="uk-flex uk-flex-center uk-margin-medium-bottom">
|
|
||||||
<button class="uk-button uk-button-primary" (click)="changeElementStatus(true)">
|
|
||||||
Change {{type}} and its contents' status
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="uk-text-small">
|
|
||||||
<p class="uk-text-bold uk-text-uppercase uk-margin-remove">Note:</p>
|
|
||||||
<div>
|
|
||||||
<span class="uk-text-bold uk-text-italic">The status of the {{type}} prevails the status of its contents.</span>
|
|
||||||
For example, if a {{type}}'s status is private, while it has
|
|
||||||
<span *ngIf="type == 'topic'">a category, subcategory or an indicator</span>
|
|
||||||
<span *ngIf="type == 'category'">a subcategory or an indicator</span>
|
|
||||||
<span *ngIf="type == 'subcategory'">an indicator</span>
|
|
||||||
that is public, the private status of the {{type}} dominates.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</modal-alert>
|
|
|
@ -1,795 +0,0 @@
|
||||||
import {
|
|
||||||
AfterViewInit,
|
|
||||||
ChangeDetectorRef,
|
|
||||||
Component, Inject,
|
|
||||||
OnDestroy,
|
|
||||||
OnInit, PLATFORM_ID,
|
|
||||||
QueryList,
|
|
||||||
ViewChild,
|
|
||||||
ViewChildren
|
|
||||||
} from '@angular/core';
|
|
||||||
import {ActivatedRoute, Router} from '@angular/router';
|
|
||||||
import {Title} from '@angular/platform-browser';
|
|
||||||
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
|
|
||||||
import {Category, Stakeholder, SubCategory, Topic, Visibility} from "../openaireLibrary/monitor/entities/stakeholder";
|
|
||||||
import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service";
|
|
||||||
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
|
|
||||||
import {AlertModal} from "../openaireLibrary/utils/modal/alert";
|
|
||||||
import {BehaviorSubject, Subject, Subscriber, Subscription} from "rxjs";
|
|
||||||
import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms";
|
|
||||||
import {StakeholderUtils} from "../utils/indicator-utils";
|
|
||||||
import {StringUtils} from "../openaireLibrary/utils/string-utils.class";
|
|
||||||
import {IDeactivateComponent} from "../openaireLibrary/utils/can-exit.guard";
|
|
||||||
import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
|
|
||||||
import {Option} from "../openaireLibrary/sharedComponents/input/input.component";
|
|
||||||
import {properties} from "../../environments/environment";
|
|
||||||
import {Session, User} from "../openaireLibrary/login/utils/helper.class";
|
|
||||||
import {UserManagementService} from "../openaireLibrary/services/user-management.service";
|
|
||||||
import {TransitionGroupComponent} from "../openaireLibrary/utils/transition-group/transition-group.component";
|
|
||||||
import {NotificationHandler} from "../openaireLibrary/utils/notification-handler";
|
|
||||||
|
|
||||||
declare var UIkit;
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'topic',
|
|
||||||
templateUrl: './topic.component.html',
|
|
||||||
})
|
|
||||||
export class TopicComponent implements OnInit, OnDestroy, AfterViewInit, IDeactivateComponent {
|
|
||||||
private topicSubscriptions: any[] = [];
|
|
||||||
private subscriptions: any[] = [];
|
|
||||||
public properties: EnvProperties = properties;
|
|
||||||
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
|
|
||||||
public loading: boolean = false;
|
|
||||||
public stakeholder: Stakeholder;
|
|
||||||
public user: User;
|
|
||||||
/**
|
|
||||||
* Stakeholder change event
|
|
||||||
* */
|
|
||||||
public change: Subject<void> = new Subject<void>();
|
|
||||||
/**
|
|
||||||
* Current topic
|
|
||||||
**/
|
|
||||||
public topicIndexSubject: BehaviorSubject<number> = new BehaviorSubject<number>(0);
|
|
||||||
public topicIndex: number = 0;
|
|
||||||
/**
|
|
||||||
* Current category
|
|
||||||
*/
|
|
||||||
public categoryIndexSubject: BehaviorSubject<number> = new BehaviorSubject<number>(0);
|
|
||||||
public categoryIndex: number = 0;
|
|
||||||
/**
|
|
||||||
* Current Subcategory
|
|
||||||
*/
|
|
||||||
public subCategoryIndexSubject: BehaviorSubject<number> = new BehaviorSubject<number>(0);
|
|
||||||
public subCategoryIndex: number = 0;
|
|
||||||
/**
|
|
||||||
* Current element and index of topic, category or subcategory to be deleted.
|
|
||||||
*/
|
|
||||||
public form: UntypedFormGroup;
|
|
||||||
public element: Topic | Category | SubCategory;
|
|
||||||
public type: 'topic' | 'category' | 'subcategory' = "topic";
|
|
||||||
public index: number = -1;
|
|
||||||
public visibility: Visibility;
|
|
||||||
|
|
||||||
@ViewChild('deleteModal', {static: true}) deleteModal: AlertModal;
|
|
||||||
@ViewChild('editModal', {static: true}) editModal: AlertModal;
|
|
||||||
@ViewChild('visibilityModal', {static: true}) visibilityModal: AlertModal;
|
|
||||||
@ViewChildren(TransitionGroupComponent) transitions: QueryList<TransitionGroupComponent>;
|
|
||||||
|
|
||||||
public elementChildrenActionOnDelete: string;
|
|
||||||
public filters: UntypedFormGroup;
|
|
||||||
public all: Option = {
|
|
||||||
value: 'all',
|
|
||||||
label: 'All'
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private route: ActivatedRoute,
|
|
||||||
private router: Router,
|
|
||||||
private title: Title,
|
|
||||||
private fb: UntypedFormBuilder,
|
|
||||||
private stakeholderService: StakeholderService,
|
|
||||||
private userManagementService: UserManagementService,
|
|
||||||
private layoutService: LayoutService,
|
|
||||||
private cdr: ChangeDetectorRef,
|
|
||||||
@Inject(PLATFORM_ID) private platformId) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ngOnInit() {
|
|
||||||
let subscription: Subscription;
|
|
||||||
this.subscriptions.push(this.topicIndexSubject.asObservable().subscribe(index => {
|
|
||||||
this.topicChanged(() => {
|
|
||||||
this.topicIndex = index;
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
this.subscriptions.push(this.categoryIndexSubject.asObservable().subscribe(index => {
|
|
||||||
this.categoryChanged(() => {
|
|
||||||
this.categoryIndex = index;
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
this.subscriptions.push(this.subCategoryIndexSubject.asObservable().subscribe(index => {
|
|
||||||
this.subCategoryChanged(() => {
|
|
||||||
this.subCategoryIndex = index;
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
this.subscriptions.push(this.route.params.subscribe(params => {
|
|
||||||
if (subscription) {
|
|
||||||
subscription.unsubscribe();
|
|
||||||
}
|
|
||||||
subscription = this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
|
|
||||||
if (stakeholder) {
|
|
||||||
this.stakeholder = stakeholder;
|
|
||||||
if (params['topic']) {
|
|
||||||
this.chooseTopic(this.stakeholder.topics.findIndex(topic => topic.alias === params['topic']));
|
|
||||||
} else {
|
|
||||||
this.chooseTopic(0);
|
|
||||||
}
|
|
||||||
this.chooseCategory(0);
|
|
||||||
this.filters = this.fb.group({
|
|
||||||
chartType: this.fb.control('all'),
|
|
||||||
status: this.fb.control('all'),
|
|
||||||
keyword: this.fb.control('')
|
|
||||||
});
|
|
||||||
if (this.topicIndex === -1) {
|
|
||||||
this.navigateToError();
|
|
||||||
} else {
|
|
||||||
this.title.setTitle(stakeholder.name + " | Indicators");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.topicSubscriptions.push(subscription);
|
|
||||||
}));
|
|
||||||
this.topicSubscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
|
|
||||||
this.user = user;
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterViewInit() {
|
|
||||||
if(this.topics) {
|
|
||||||
let activeIndex = UIkit.nav(this.topics.element.nativeElement).items.findIndex(item => item.classList.contains('uk-open'));
|
|
||||||
if(activeIndex !== this.topicIndex) {
|
|
||||||
setTimeout(() => {
|
|
||||||
UIkit.nav(this.topics.element.nativeElement).toggle(this.topicIndex, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get isBrowser() {
|
|
||||||
return this.platformId === 'browser';
|
|
||||||
}
|
|
||||||
|
|
||||||
public ngOnDestroy() {
|
|
||||||
this.topicSubscriptions.forEach(value => {
|
|
||||||
if (value instanceof Subscriber) {
|
|
||||||
value.unsubscribe();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.subscriptions.forEach(value => {
|
|
||||||
if (value instanceof Subscriber) {
|
|
||||||
value.unsubscribe();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
canExit(): boolean {
|
|
||||||
this.topicSubscriptions.forEach(value => {
|
|
||||||
if (value instanceof Subscriber) {
|
|
||||||
value.unsubscribe();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.stakeholderService.setStakeholder(this.stakeholder);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private findById(id: string) {
|
|
||||||
return this.transitions?this.transitions.find(item => item.id === id):null;
|
|
||||||
}
|
|
||||||
|
|
||||||
get topics(): TransitionGroupComponent {
|
|
||||||
return this.findById('topics');
|
|
||||||
}
|
|
||||||
|
|
||||||
get categories(): TransitionGroupComponent {
|
|
||||||
return this.findById('categories-' + this.topicIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
get subCategories(): TransitionGroupComponent {
|
|
||||||
return this.findById('subCategories');
|
|
||||||
}
|
|
||||||
|
|
||||||
hide(element: any) {
|
|
||||||
UIkit.dropdown(element).hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
stakeholderChanged() {
|
|
||||||
this.change.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
public saveElement() {
|
|
||||||
if (this.type === "topic") {
|
|
||||||
this.saveTopic();
|
|
||||||
} else if (this.type === "category") {
|
|
||||||
this.saveCategory();
|
|
||||||
} else {
|
|
||||||
this.saveSubCategory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public deleteElement() {
|
|
||||||
if (this.type === "topic") {
|
|
||||||
this.deleteTopic();
|
|
||||||
} else if (this.type === "category") {
|
|
||||||
this.deleteCategory();
|
|
||||||
} else {
|
|
||||||
this.deleteSubcategory();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public changeElementStatus(propagate: boolean = false) {
|
|
||||||
if (this.type === "topic") {
|
|
||||||
this.changeTopicStatus(propagate);
|
|
||||||
} else if (this.type === "category") {
|
|
||||||
this.changeCategoryStatus(propagate);
|
|
||||||
} else {
|
|
||||||
this.changeSubcategoryStatus(propagate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public chooseTopic(topicIndex: number) {
|
|
||||||
this.topicIndexSubject.next(topicIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
topicChanged(callback: Function, save: boolean = false) {
|
|
||||||
if(this.topics && save) {
|
|
||||||
this.topics.disable();
|
|
||||||
}
|
|
||||||
if(this.categories) {
|
|
||||||
this.categories.disable();
|
|
||||||
}
|
|
||||||
if(this.subCategories) {
|
|
||||||
this.subCategories.disable();
|
|
||||||
}
|
|
||||||
if(callback) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
this.cdr.detectChanges();
|
|
||||||
if(this.topics && save) {
|
|
||||||
this.topics.init();
|
|
||||||
this.topics.enable();
|
|
||||||
}
|
|
||||||
if(this.categories) {
|
|
||||||
this.categories.init();
|
|
||||||
this.categories.enable();
|
|
||||||
}
|
|
||||||
if(this.subCategories) {
|
|
||||||
this.subCategories.init();
|
|
||||||
this.subCategories.enable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private buildTopic(topic: Topic) {
|
|
||||||
let topics = this.stakeholder.topics.filter(element => element._id !== topic._id);
|
|
||||||
this.form = this.fb.group({
|
|
||||||
_id: this.fb.control(topic._id),
|
|
||||||
name: this.fb.control(topic.name, Validators.required),
|
|
||||||
description: this.fb.control(topic.description),
|
|
||||||
creationDate: this.fb.control(topic.creationDate),
|
|
||||||
alias: this.fb.control(topic.alias, [
|
|
||||||
Validators.required,
|
|
||||||
this.stakeholderUtils.aliasValidator(topics)
|
|
||||||
]
|
|
||||||
),
|
|
||||||
visibility: this.fb.control(topic.visibility),
|
|
||||||
defaultId: this.fb.control(topic.defaultId),
|
|
||||||
categories: this.fb.control(topic.categories),
|
|
||||||
icon: this.fb.control(topic.icon)
|
|
||||||
});
|
|
||||||
this.topicSubscriptions.push(this.form.get('name').valueChanges.subscribe(value => {
|
|
||||||
let i = 1;
|
|
||||||
value = this.stakeholderUtils.generateAlias(value);
|
|
||||||
this.form.controls['alias'].setValue(value);
|
|
||||||
while (this.form.get('alias').invalid) {
|
|
||||||
this.form.controls['alias'].setValue(value + i);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
public editTopicOpen(index = -1) {
|
|
||||||
this.index = index;
|
|
||||||
this.type = 'topic';
|
|
||||||
if (index === -1) {
|
|
||||||
this.buildTopic(new Topic(null, null, null, "PUBLIC"));
|
|
||||||
} else {
|
|
||||||
this.buildTopic(this.stakeholder.topics[index]);
|
|
||||||
}
|
|
||||||
this.editOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
public saveTopic() {
|
|
||||||
if (!this.form.invalid) {
|
|
||||||
let path = [this.stakeholder._id];
|
|
||||||
let callback = (topic: Topic): void => {
|
|
||||||
this.topicChanged(() => {
|
|
||||||
if (this.index === -1) {
|
|
||||||
this.stakeholder.topics.push(topic);
|
|
||||||
} else {
|
|
||||||
this.stakeholder.topics[this.index] = HelperFunctions.copy(topic);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
};
|
|
||||||
if (this.index === -1) {
|
|
||||||
this.save('Topic has been successfully created', path, this.form.value, callback);
|
|
||||||
} else {
|
|
||||||
this.save('Topic has been successfully saved', path, this.form.value, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public changeTopicStatus(propagate: boolean = false) {
|
|
||||||
let path = [
|
|
||||||
this.stakeholder._id,
|
|
||||||
this.stakeholder.topics[this.index]._id
|
|
||||||
];
|
|
||||||
let callback = (topic: Topic): void => {
|
|
||||||
this.topicChanged(() => {
|
|
||||||
this.stakeholder.topics[this.index] = HelperFunctions.copy(topic);
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
this.changeStatus(this.stakeholder.topics[this.index], path, this.visibility, callback, propagate);
|
|
||||||
this.visibilityModal.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
public deleteTopicOpen(index = this.topicIndex, childrenAction: string = null) {
|
|
||||||
this.type = 'topic';
|
|
||||||
this.index = index;
|
|
||||||
this.element = this.stakeholder.topics[this.index];
|
|
||||||
this.deleteOpen(childrenAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public deleteTopic() {
|
|
||||||
let path: string[] = [
|
|
||||||
this.stakeholder._id,
|
|
||||||
this.stakeholder.topics[this.index]._id
|
|
||||||
];
|
|
||||||
let callback = (): void => {
|
|
||||||
this.topicChanged(() => {
|
|
||||||
this.stakeholder.topics.splice(this.index, 1);
|
|
||||||
if(this.topicIndex === this.index) {
|
|
||||||
this.chooseTopic(Math.max(0, this.index - 1));
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
};
|
|
||||||
this.delete('Topic has been successfully be deleted', path, callback, (this.topicIndex === this.index));
|
|
||||||
}
|
|
||||||
|
|
||||||
public moveTopic(index: number, newIndex: number = index - 1) {
|
|
||||||
this.topics.init();
|
|
||||||
let path = [this.stakeholder._id];
|
|
||||||
let ids = this.stakeholder.topics.map(topic => topic._id);
|
|
||||||
HelperFunctions.swap(ids, index, newIndex);
|
|
||||||
this.stakeholderService.reorderElements(properties.monitorServiceAPIURL, path, ids).subscribe(() => {
|
|
||||||
HelperFunctions.swap(this.stakeholder.topics, index, newIndex);
|
|
||||||
if(this.topicIndex === index) {
|
|
||||||
this.chooseTopic(newIndex);
|
|
||||||
} else if(this.topicIndex === newIndex) {
|
|
||||||
this.chooseTopic(index);
|
|
||||||
}
|
|
||||||
}, error => {
|
|
||||||
NotificationHandler.rise(error.error.message)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public chooseCategory(index: number) {
|
|
||||||
this.categoryIndexSubject.next(index);
|
|
||||||
this.chooseSubcategory(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
categoryChanged(callback: Function, save: boolean = false) {
|
|
||||||
if(this.categories && save) {
|
|
||||||
this.categories.disable();
|
|
||||||
}
|
|
||||||
if(this.subCategories) {
|
|
||||||
this.subCategories.disable();
|
|
||||||
}
|
|
||||||
if(callback) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
this.cdr.detectChanges();
|
|
||||||
if(this.categories && save) {
|
|
||||||
this.categories.init();
|
|
||||||
this.categories.enable();
|
|
||||||
}
|
|
||||||
if(this.subCategories) {
|
|
||||||
this.subCategories.init();
|
|
||||||
this.subCategories.enable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private buildCategory(category: Category) {
|
|
||||||
let categories = this.stakeholder.topics[this.topicIndex].categories.filter(element => element._id !== category._id);
|
|
||||||
this.form = this.fb.group({
|
|
||||||
_id: this.fb.control(category._id),
|
|
||||||
name: this.fb.control(category.name, Validators.required),
|
|
||||||
description: this.fb.control(category.description),
|
|
||||||
creationDate: this.fb.control(category.creationDate),
|
|
||||||
alias: this.fb.control(category.alias, [
|
|
||||||
Validators.required,
|
|
||||||
this.stakeholderUtils.aliasValidator(categories)
|
|
||||||
]
|
|
||||||
),
|
|
||||||
visibility: this.fb.control(category.visibility),
|
|
||||||
defaultId: this.fb.control(category.defaultId),
|
|
||||||
subCategories: this.fb.control(category.subCategories)
|
|
||||||
});
|
|
||||||
this.topicSubscriptions.push(this.form.get('name').valueChanges.subscribe(value => {
|
|
||||||
let i = 1;
|
|
||||||
value = this.stakeholderUtils.generateAlias(value);
|
|
||||||
this.form.controls['alias'].setValue(value);
|
|
||||||
while (this.form.get('alias').invalid) {
|
|
||||||
this.form.controls['alias'].setValue(value + i);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
public editCategoryOpen(index: number = -1) {
|
|
||||||
this.index = index;
|
|
||||||
this.type = 'category';
|
|
||||||
if (index === -1) {
|
|
||||||
this.buildCategory(new Category(null, null, null, "PUBLIC"));
|
|
||||||
} else {
|
|
||||||
this.buildCategory(this.stakeholder.topics[this.topicIndex].categories[index]);
|
|
||||||
}
|
|
||||||
this.editOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
public saveCategory() {
|
|
||||||
if (!this.form.invalid) {
|
|
||||||
let path = [this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id];
|
|
||||||
let callback = (category: Category): void => {
|
|
||||||
this.categoryChanged(() => {
|
|
||||||
if (this.index === -1) {
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories.push(category);
|
|
||||||
this.categories.init();
|
|
||||||
} else {
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories[this.index] = HelperFunctions.copy(category);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
};
|
|
||||||
if (this.index === -1) {
|
|
||||||
this.save('Category has been successfully created', path, this.form.value, callback);
|
|
||||||
} else {
|
|
||||||
this.save('Category has been successfully saved', path, this.form.value, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public changeCategoryStatus(propagate: boolean = false) {
|
|
||||||
let path = [
|
|
||||||
this.stakeholder._id,
|
|
||||||
this.stakeholder.topics[this.topicIndex]._id,
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories[this.index]._id
|
|
||||||
];
|
|
||||||
let callback = (category: Category): void => {
|
|
||||||
this.categoryChanged(() => {
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories[this.index] = HelperFunctions.copy(category);
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
this.changeStatus(this.stakeholder.topics[this.topicIndex].categories[this.index], path, this.visibility, callback, propagate);
|
|
||||||
this.visibilityModal.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
public deleteCategoryOpen(index: number, childrenAction: string = null) {
|
|
||||||
this.type = 'category';
|
|
||||||
this.index = index;
|
|
||||||
this.element = this.stakeholder.topics[this.topicIndex].categories[this.index];
|
|
||||||
this.deleteOpen(childrenAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public deleteCategory() {
|
|
||||||
let path: string[] = [
|
|
||||||
this.stakeholder._id,
|
|
||||||
this.stakeholder.topics[this.topicIndex]._id,
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories[this.index]._id
|
|
||||||
];
|
|
||||||
let callback = (): void => {
|
|
||||||
this.categoryChanged(() => {
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories.splice(this.index, 1);
|
|
||||||
if(this.categoryIndex === this.index) {
|
|
||||||
this.chooseCategory(Math.max(0, this.index - 1));
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
};
|
|
||||||
this.delete('Category has been successfully be deleted', path, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public moveCategory(index: number, newIndex: number = index - 1) {
|
|
||||||
this.categories.init();
|
|
||||||
let path = [this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id];
|
|
||||||
let ids = this.stakeholder.topics[this.topicIndex].categories.map(category => category._id);
|
|
||||||
HelperFunctions.swap(ids, index, newIndex);
|
|
||||||
this.stakeholderService.reorderElements(properties.monitorServiceAPIURL, path, ids).subscribe(() => {
|
|
||||||
HelperFunctions.swap(this.stakeholder.topics[this.topicIndex].categories, index, newIndex);
|
|
||||||
if(this.categoryIndex === index) {
|
|
||||||
this.chooseCategory(newIndex);
|
|
||||||
} else if(this.categoryIndex === newIndex) {
|
|
||||||
this.chooseCategory(index);
|
|
||||||
}
|
|
||||||
}, error => {
|
|
||||||
NotificationHandler.rise(error.error.message)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
chooseSubcategory(subcategoryIndex: number) {
|
|
||||||
this.subCategoryIndexSubject.next(subcategoryIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
subCategoryChanged(callback: Function, save: boolean = false) {
|
|
||||||
if(this.subCategories && save) {
|
|
||||||
this.subCategories.disable();
|
|
||||||
}
|
|
||||||
if(callback) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
this.cdr.detectChanges();
|
|
||||||
if(this.subCategories && save) {
|
|
||||||
this.subCategories.init();
|
|
||||||
this.subCategories.enable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private buildSubcategory(subCategory: SubCategory) {
|
|
||||||
let subCategories = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.filter(element => element._id !== subCategory._id);
|
|
||||||
this.form = this.fb.group({
|
|
||||||
_id: this.fb.control(subCategory._id),
|
|
||||||
name: this.fb.control(subCategory.name, Validators.required),
|
|
||||||
description: this.fb.control(subCategory.description),
|
|
||||||
creationDate: this.fb.control(subCategory.creationDate),
|
|
||||||
alias: this.fb.control(subCategory.alias, [
|
|
||||||
Validators.required,
|
|
||||||
this.stakeholderUtils.aliasValidator(subCategories)
|
|
||||||
]
|
|
||||||
),
|
|
||||||
visibility: this.fb.control(subCategory.visibility),
|
|
||||||
defaultId: this.fb.control(subCategory.defaultId),
|
|
||||||
charts: this.fb.control(subCategory.charts),
|
|
||||||
numbers: this.fb.control(subCategory.numbers)
|
|
||||||
});
|
|
||||||
this.topicSubscriptions.push(this.form.get('name').valueChanges.subscribe(value => {
|
|
||||||
let i = 1;
|
|
||||||
value = this.stakeholderUtils.generateAlias(value);
|
|
||||||
this.form.controls['alias'].setValue(value);
|
|
||||||
while (this.form.get('alias').invalid) {
|
|
||||||
this.form.controls['alias'].setValue(value + i);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
public editSubCategoryOpen(index: number = -1) {
|
|
||||||
this.index = index;
|
|
||||||
this.type = 'subcategory';
|
|
||||||
if (index === -1) {
|
|
||||||
this.buildSubcategory(new SubCategory(null, null, null, "PUBLIC"));
|
|
||||||
} else {
|
|
||||||
this.buildSubcategory(this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[index]);
|
|
||||||
}
|
|
||||||
this.editOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
public saveSubCategory() {
|
|
||||||
if (!this.form.invalid) {
|
|
||||||
let path: string[] = [
|
|
||||||
this.stakeholder._id,
|
|
||||||
this.stakeholder.topics[this.topicIndex]._id,
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id
|
|
||||||
];
|
|
||||||
let callback = (subCategory: SubCategory): void => {
|
|
||||||
this.subCategoryChanged(() => {
|
|
||||||
if (this.index === -1) {
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.push(subCategory);
|
|
||||||
} else {
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index] = HelperFunctions.copy(subCategory);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
};
|
|
||||||
if (this.index === -1) {
|
|
||||||
this.save('Subcategory has been successfully created', path, this.form.value, callback);
|
|
||||||
} else {
|
|
||||||
this.save('Subcategory has been successfully saved', path, this.form.value, callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public changeSubcategoryStatus(propagate: boolean = false) {
|
|
||||||
let path = [
|
|
||||||
this.stakeholder._id,
|
|
||||||
this.stakeholder.topics[this.topicIndex]._id,
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id,
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index]._id
|
|
||||||
];
|
|
||||||
let callback = (subcategory: SubCategory): void => {
|
|
||||||
this.subCategoryChanged(() => {
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index] = HelperFunctions.copy(subcategory);
|
|
||||||
}, true);
|
|
||||||
}
|
|
||||||
this.changeStatus(this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index], path, this.visibility, callback, propagate);
|
|
||||||
this.visibilityModal.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public deleteSubcategoryOpen(index, childrenAction: string = null) {
|
|
||||||
this.type = 'subcategory';
|
|
||||||
this.index = index;
|
|
||||||
this.element = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index];
|
|
||||||
this.deleteOpen(childrenAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public deleteSubcategory() {
|
|
||||||
let path: string[] = [
|
|
||||||
this.stakeholder._id,
|
|
||||||
this.stakeholder.topics[this.topicIndex]._id,
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id,
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index]._id
|
|
||||||
];
|
|
||||||
let callback = (): void => {
|
|
||||||
this.subCategoryChanged(() => {
|
|
||||||
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.splice(this.index, 1);
|
|
||||||
if(this.subCategoryIndex === this.index) {
|
|
||||||
this.chooseSubcategory(Math.max(0, this.index - 1));
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
};
|
|
||||||
this.delete('Subcategory has been successfully be deleted', path, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public moveSubCategory(index: number, newIndex: number = index - 1) {
|
|
||||||
this.subCategories.init();
|
|
||||||
let path = [this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id];
|
|
||||||
let ids = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.map(subCategory => subCategory._id);
|
|
||||||
HelperFunctions.swap(ids, index, newIndex);
|
|
||||||
this.stakeholderService.reorderElements(properties.monitorServiceAPIURL, path, ids).subscribe(() => {
|
|
||||||
HelperFunctions.swap(this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories, index, newIndex);
|
|
||||||
if(this.subCategoryIndex === index) {
|
|
||||||
this.chooseSubcategory(newIndex);
|
|
||||||
} else if(this.subCategoryIndex === newIndex) {
|
|
||||||
this.chooseSubcategory(index);
|
|
||||||
}
|
|
||||||
}, error => {
|
|
||||||
NotificationHandler.rise(error.error.message)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private navigateToError() {
|
|
||||||
this.router.navigate([this.properties.errorLink], {queryParams: {'page': this.router.url}});
|
|
||||||
}
|
|
||||||
|
|
||||||
get isCurator(): boolean {
|
|
||||||
return Session.isPortalAdministrator(this.user) || Session.isCurator(this.stakeholder.type, this.user);
|
|
||||||
}
|
|
||||||
|
|
||||||
private editOpen() {
|
|
||||||
this.editModal.cancelButtonText = 'Cancel';
|
|
||||||
this.editModal.okButtonLeft = false;
|
|
||||||
this.editModal.alertMessage = false;
|
|
||||||
if (this.index === -1) {
|
|
||||||
this.editModal.alertTitle = 'Create a new ' + this.type;
|
|
||||||
this.editModal.okButtonText = 'Create';
|
|
||||||
} else {
|
|
||||||
this.editModal.alertTitle = 'Edit ' + this.type + '\'s information ';
|
|
||||||
this.editModal.okButtonText = 'Save';
|
|
||||||
}
|
|
||||||
this.editModal.stayOpen = true;
|
|
||||||
this.editModal.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
private deleteOpen(childrenAction: string = null) {
|
|
||||||
this.elementChildrenActionOnDelete = null;
|
|
||||||
if (childrenAction == "delete") {
|
|
||||||
this.elementChildrenActionOnDelete = childrenAction;
|
|
||||||
} else if (childrenAction == "disconnect") {
|
|
||||||
this.elementChildrenActionOnDelete = childrenAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.deleteModal.alertTitle = 'Delete ' + this.type;
|
|
||||||
this.deleteModal.cancelButtonText = 'No';
|
|
||||||
this.deleteModal.okButtonText = 'Yes';
|
|
||||||
// this.deleteModal.cancelButton = false;
|
|
||||||
// this.deleteModal.okButton = false;
|
|
||||||
this.deleteModal.stayOpen = true;
|
|
||||||
this.deleteModal.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
private save(message: string, path: string[], saveElement: any, callback: Function, redirect = false) {
|
|
||||||
this.loading = true;
|
|
||||||
this.topicSubscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, saveElement, path).subscribe(saveElement => {
|
|
||||||
callback(saveElement);
|
|
||||||
this.stakeholderChanged();
|
|
||||||
this.loading = false;
|
|
||||||
this.editModal.cancel();
|
|
||||||
NotificationHandler.rise(message);
|
|
||||||
if (redirect) {
|
|
||||||
this.router.navigate(['../' + saveElement.alias], {
|
|
||||||
relativeTo: this.route
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, error => {
|
|
||||||
this.loading = false;
|
|
||||||
this.editModal.cancel();
|
|
||||||
NotificationHandler.rise(error.error.message, 'danger');
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
private delete(message: string, path: string[], callback: Function, redirect = false) {
|
|
||||||
this.loading = true;
|
|
||||||
this.topicSubscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path, this.elementChildrenActionOnDelete).subscribe(() => {
|
|
||||||
callback();
|
|
||||||
this.stakeholderChanged();
|
|
||||||
this.loading = false;
|
|
||||||
this.deleteModal.cancel();
|
|
||||||
NotificationHandler.rise(message);
|
|
||||||
if (redirect) {
|
|
||||||
this.back();
|
|
||||||
}
|
|
||||||
}, error => {
|
|
||||||
this.loading = false;
|
|
||||||
this.deleteModal.cancel();
|
|
||||||
NotificationHandler.rise(error.error.message, 'danger');
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
private changeStatus(element: Topic | Category | SubCategory, path: string[], visibility: Visibility, callback: Function = null, propagate: boolean = false) {
|
|
||||||
this.topicSubscriptions.push(this.stakeholderService.changeVisibility(this.properties.monitorServiceAPIURL, path, visibility, propagate).subscribe(returnedElement => {
|
|
||||||
if(propagate) {
|
|
||||||
callback(returnedElement);
|
|
||||||
NotificationHandler.rise(StringUtils.capitalize(this.type) + ' has been <b>successfully changed</b> to ' + returnedElement.visibility.toLowerCase());
|
|
||||||
} else {
|
|
||||||
element.visibility = returnedElement.visibility;
|
|
||||||
NotificationHandler.rise(StringUtils.capitalize(this.type) + ' has been <b>successfully changed</b> to ' + element.visibility.toLowerCase());
|
|
||||||
}
|
|
||||||
}, error => {
|
|
||||||
NotificationHandler.rise(error.error.message, 'danger');
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
back() {
|
|
||||||
this.router.navigate(['../'], {
|
|
||||||
relativeTo: this.route
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public getPluralTypeName(): string {
|
|
||||||
if (this.type == "topic") {
|
|
||||||
return "Topics";
|
|
||||||
} else if (this.type == "category") {
|
|
||||||
return "Categories";
|
|
||||||
} else if (this.type == "subcategory") {
|
|
||||||
return "Subcategories";
|
|
||||||
} else {
|
|
||||||
return this.type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public get isSmallScreen() {
|
|
||||||
return this.layoutService.isSmallScreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get open() {
|
|
||||||
return this.layoutService.open;
|
|
||||||
}
|
|
||||||
|
|
||||||
public toggleOpen(event: MouseEvent) {
|
|
||||||
event.preventDefault();
|
|
||||||
this.layoutService.setOpen(!this.open);
|
|
||||||
}
|
|
||||||
|
|
||||||
public openVisibilityModal(index: number, visibility: Visibility, type: any) {
|
|
||||||
this.index = index;
|
|
||||||
this.visibility = visibility;
|
|
||||||
this.type = type;
|
|
||||||
this.visibilityModal.alertTitle = 'Visibility Status';
|
|
||||||
this.visibilityModal.alertFooter = false;
|
|
||||||
this.visibilityModal.open();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
import {NgModule} from '@angular/core';
|
|
||||||
import {CommonModule} from '@angular/common';
|
|
||||||
|
|
||||||
import {PreviousRouteRecorder} from '../openaireLibrary/utils/piwik/previousRouteRecorder.guard';
|
|
||||||
|
|
||||||
import {PiwikService} from '../openaireLibrary/utils/piwik/piwik.service';
|
|
||||||
import {TopicComponent} from "./topic.component";
|
|
||||||
import {TopicRoutingModule} from "./topic-routing.module";
|
|
||||||
import {RouterModule} from "@angular/router";
|
|
||||||
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
|
|
||||||
import {IndicatorsComponent} from "./indicators.component";
|
|
||||||
import {AlertModalModule} from "../openaireLibrary/utils/modal/alertModal.module";
|
|
||||||
import {InputModule} from "../openaireLibrary/sharedComponents/input/input.module";
|
|
||||||
import {ClickModule} from "../openaireLibrary/utils/click/click.module";
|
|
||||||
import {IconsService} from "../openaireLibrary/utils/icons/icons.service";
|
|
||||||
import {earth, incognito, restricted} from "../openaireLibrary/utils/icons/icons";
|
|
||||||
import {IconsModule} from "../openaireLibrary/utils/icons/icons.module";
|
|
||||||
import {PageContentModule} from "../openaireLibrary/dashboard/sharedComponents/page-content/page-content.module";
|
|
||||||
import {LoadingModule} from "../openaireLibrary/utils/loading/loading.module";
|
|
||||||
import {NotifyFormModule} from "../openaireLibrary/notifications/notify-form/notify-form.module";
|
|
||||||
import {LogoUrlPipeModule} from "../openaireLibrary/utils/pipes/logoUrlPipe.module";
|
|
||||||
import {TransitionGroupModule} from "../openaireLibrary/utils/transition-group/transition-group.module";
|
|
||||||
import {NumberRoundModule} from "../openaireLibrary/utils/pipes/number-round.module";
|
|
||||||
import {SideBarModule} from "../openaireLibrary/dashboard/sharedComponents/sidebar/sideBar.module";
|
|
||||||
import {
|
|
||||||
SidebarMobileToggleModule
|
|
||||||
} from "../openaireLibrary/dashboard/sharedComponents/sidebar/sidebar-mobile-toggle/sidebar-mobile-toggle.module";
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
CommonModule, TopicRoutingModule, ClickModule, RouterModule, FormsModule, AlertModalModule,
|
|
||||||
ReactiveFormsModule, InputModule, IconsModule, PageContentModule, LoadingModule, NotifyFormModule, LogoUrlPipeModule, TransitionGroupModule, NumberRoundModule, SideBarModule, SidebarMobileToggleModule
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
TopicComponent, IndicatorsComponent
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
PreviousRouteRecorder,
|
|
||||||
PiwikService
|
|
||||||
],
|
|
||||||
exports: [
|
|
||||||
TopicComponent
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class TopicModule {
|
|
||||||
constructor(private iconsService: IconsService) {
|
|
||||||
this.iconsService.registerIcons([earth, incognito, restricted]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
import {Injectable} from '@angular/core';
|
|
||||||
import {
|
|
||||||
ActivatedRouteSnapshot,
|
|
||||||
CanActivate,
|
|
||||||
CanActivateChild,
|
|
||||||
Router,
|
|
||||||
RouterStateSnapshot,
|
|
||||||
UrlTree
|
|
||||||
} from '@angular/router';
|
|
||||||
import {map, take, tap} from "rxjs/operators";
|
|
||||||
import {UserManagementService} from "../openaireLibrary/services/user-management.service";
|
|
||||||
import {LoginErrorCodes} from "../openaireLibrary/login/utils/guardHelper.class";
|
|
||||||
import {Session} from "../openaireLibrary/login/utils/helper.class";
|
|
||||||
import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service";
|
|
||||||
import {Observable, zip} from "rxjs";
|
|
||||||
import {error} from "protractor";
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class AdminDashboardGuard implements CanActivate, CanActivateChild {
|
|
||||||
|
|
||||||
constructor(private router: Router,
|
|
||||||
private stakeholderService: StakeholderService,
|
|
||||||
private userManagementService: UserManagementService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
check(path: string, alias: string): Observable<boolean> | boolean {
|
|
||||||
let errorCode = LoginErrorCodes.NOT_LOGIN;
|
|
||||||
return zip(
|
|
||||||
this.userManagementService.getUserInfo(), this.stakeholderService.getStakeholder(alias)
|
|
||||||
).pipe(take(1),map(res => {
|
|
||||||
if(res[0]) {
|
|
||||||
errorCode = LoginErrorCodes.NOT_ADMIN;
|
|
||||||
}
|
|
||||||
return res[0] && res[1] && (Session.isPortalAdministrator(res[0]) ||
|
|
||||||
Session.isCurator(res[1].type, res[0]) || Session.isManager(res[1].type, res[1].alias, res[0]))
|
|
||||||
}),tap(authorized => {
|
|
||||||
if(!authorized){
|
|
||||||
this.router.navigate(['/user-info'], {queryParams: {'errorCode': errorCode, 'redirectUrl':path}});
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
|
|
||||||
return this.check(state.url, route.params.stakeholder);
|
|
||||||
}
|
|
||||||
|
|
||||||
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
|
|
||||||
return this.check(state.url, childRoute.params.stakeholder);
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,26 +0,0 @@
|
||||||
import {Injectable} from "@angular/core";
|
|
||||||
import {HttpClient} from "@angular/common/http";
|
|
||||||
import {properties} from "../../../environments/environment";
|
|
||||||
import {BehaviorSubject, Observable} from "rxjs";
|
|
||||||
import {CustomOptions} from "../../openaireLibrary/services/servicesUtils/customOptions.class";
|
|
||||||
import {map, tap} from "rxjs/operators";
|
|
||||||
import {Report} from "../../../cache-indicators";
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class CacheIndicatorsService {
|
|
||||||
|
|
||||||
constructor(private http: HttpClient) {
|
|
||||||
}
|
|
||||||
|
|
||||||
createReport(alias: string) {
|
|
||||||
return this.http.post<any>(properties.domain + properties.baseLink + '/cache/' + alias, {}, CustomOptions.registryOptions())
|
|
||||||
.pipe(map(res => res.report));
|
|
||||||
}
|
|
||||||
|
|
||||||
getReport(alias: string) {
|
|
||||||
return this.http.get<any>(properties.domain + properties.baseLink + '/cache/' + alias, CustomOptions.registryOptions())
|
|
||||||
.pipe(map(res => res.report));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
import {Injectable} from '@angular/core';
|
|
||||||
import {HttpClient} from "@angular/common/http";
|
|
||||||
import {Observable} from "rxjs";
|
|
||||||
import {SourceType} from "../../openaireLibrary/monitor/entities/stakeholder";
|
|
||||||
import {properties} from "../../../environments/environment";
|
|
||||||
import {IndicatorUtils} from "../indicator-utils";
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class StatisticsService {
|
|
||||||
|
|
||||||
indicatorsUtils = new IndicatorUtils();
|
|
||||||
|
|
||||||
constructor(private http: HttpClient) {}
|
|
||||||
|
|
||||||
getNumbers(source: SourceType, url: string): Observable<any> {
|
|
||||||
if (source !== null) {
|
|
||||||
return this.http.get<any>(this.indicatorsUtils.getNumberUrl(source, url));
|
|
||||||
} else {
|
|
||||||
return this.http.get<any>(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
import {Injectable} from "@angular/core";
|
|
||||||
import {HttpClient} from "@angular/common/http";
|
|
||||||
import {properties} from "../../../environments/environment";
|
|
||||||
import {Observable} from "rxjs";
|
|
||||||
import {CustomOptions} from "../../openaireLibrary/services/servicesUtils/customOptions.class";
|
|
||||||
import {map} from "rxjs/operators";
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class StatsProfilesService {
|
|
||||||
|
|
||||||
constructor(private http: HttpClient) {
|
|
||||||
}
|
|
||||||
|
|
||||||
getStatsProfiles(): Observable<string[]> {
|
|
||||||
return this.http.get<any[]>(properties.monitorStatsFrameUrl + 'schema/profiles')
|
|
||||||
.pipe(map(profiles => profiles.map(profile => profile.name)));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit d18e0a7e43e5ab74649481ecbf352ba49893c66f
|
Subproject commit d1b2d5e585722751792d12645d17f820cd6a7860
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2df4b377a3e89b7dd26a011a2e1e1f07fdcedf2a
|
Subproject commit 2dadcf85926bc0f11fff22ed94dc197ddd8587c6
|
|
@ -1,262 +0,0 @@
|
||||||
import {IndicatorType, Stakeholder} from "./app/openaireLibrary/monitor/entities/stakeholder";
|
|
||||||
import axios from "axios";
|
|
||||||
import {IndicatorUtils} from "./app/utils/indicator-utils";
|
|
||||||
import {Composer} from "./app/openaireLibrary/utils/email/composer";
|
|
||||||
import {properties} from "./environments/environment";
|
|
||||||
import {error} from "protractor";
|
|
||||||
|
|
||||||
|
|
||||||
export interface CacheItem {
|
|
||||||
reportId: string,
|
|
||||||
type: IndicatorType,
|
|
||||||
url: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Report {
|
|
||||||
creator: string;
|
|
||||||
name: string;
|
|
||||||
success: number;
|
|
||||||
errors: {
|
|
||||||
url: string,
|
|
||||||
status: number
|
|
||||||
}[];
|
|
||||||
total: number;
|
|
||||||
completed: boolean;
|
|
||||||
percentage: number
|
|
||||||
|
|
||||||
constructor(total: number, name: string, creator: string) {
|
|
||||||
this.creator = creator;
|
|
||||||
this.name = name;
|
|
||||||
this.success = 0;
|
|
||||||
this.errors = [];
|
|
||||||
this.total = total;
|
|
||||||
this.completed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
setPercentage() {
|
|
||||||
this.percentage = Math.floor((this.success + this.errors.length) / this.total * 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CacheIndicators {
|
|
||||||
|
|
||||||
private static BATCH_SIZE = 10;
|
|
||||||
|
|
||||||
private reports: Map<string, Report> = new Map<string, Report>();
|
|
||||||
private queue: CacheItem[] = [];
|
|
||||||
private process: Promise<void>;
|
|
||||||
private isFinished: boolean = true;
|
|
||||||
|
|
||||||
stakeholderToCacheItems(stakeholder: Stakeholder) {
|
|
||||||
let cacheItems: CacheItem[] = [];
|
|
||||||
let indicatorUtils = new IndicatorUtils();
|
|
||||||
stakeholder.topics.forEach(topic => {
|
|
||||||
topic.categories.forEach(category => {
|
|
||||||
category.subCategories.forEach(subCategory => {
|
|
||||||
subCategory.numbers.forEach(section => {
|
|
||||||
section.indicators.forEach(indicator => {
|
|
||||||
indicator.indicatorPaths.forEach(indicatorPath => {
|
|
||||||
let url = indicatorUtils.getNumberUrl(indicatorPath.source, indicatorUtils.getFullUrl(stakeholder, indicatorPath));
|
|
||||||
cacheItems.push({
|
|
||||||
reportId: stakeholder._id,
|
|
||||||
type: 'number',
|
|
||||||
url: url
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
subCategory.charts.forEach(section => {
|
|
||||||
section.indicators.forEach(indicator => {
|
|
||||||
indicator.indicatorPaths.forEach(indicatorPath => {
|
|
||||||
let url = indicatorUtils.getChartUrl(indicatorPath.source, indicatorUtils.getFullUrl(stakeholder, indicatorPath));
|
|
||||||
cacheItems.push({
|
|
||||||
reportId: stakeholder._id,
|
|
||||||
type: 'chart',
|
|
||||||
url: url
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return cacheItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
public exists(id: string) {
|
|
||||||
return this.reports.has(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public completed(id: string) {
|
|
||||||
return !this.exists(id) || this.reports.get(id).completed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public createReport(id: string, cacheItems: CacheItem[], name: string, creator: string) {
|
|
||||||
let report = new Report(cacheItems.length, name, creator);
|
|
||||||
this.reports.set(id, report);
|
|
||||||
this.addItemsToQueue(cacheItems);
|
|
||||||
return report;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getReport(id: string) {
|
|
||||||
return this.reports.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async processQueue() {
|
|
||||||
this.isFinished = false;
|
|
||||||
while (this.queue.length > 0) {
|
|
||||||
let batch = this.queue.splice(0, CacheIndicators.BATCH_SIZE);
|
|
||||||
await this.processBatch(batch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async processBatch(batch: CacheItem[]) {
|
|
||||||
let promises: Promise<any>[] = [];
|
|
||||||
let ids = new Set<string>();
|
|
||||||
batch.forEach(item => {
|
|
||||||
let promise;
|
|
||||||
ids.add(item.reportId);
|
|
||||||
if (item.type === 'chart') {
|
|
||||||
let [url, json] = item.url.split('?json=');
|
|
||||||
json = decodeURIComponent(json);
|
|
||||||
json = statsToolParser(JSON.parse(json));
|
|
||||||
promise = axios.post(url, json);
|
|
||||||
} else {
|
|
||||||
promise = axios.get(item.url);
|
|
||||||
}
|
|
||||||
promises.push(promise.then(response => {
|
|
||||||
let report = this.reports.get(item.reportId);
|
|
||||||
if (report) {
|
|
||||||
report.success++;
|
|
||||||
report.setPercentage();
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
}).catch(error => {
|
|
||||||
let report = this.reports.get(item.reportId);
|
|
||||||
if (report) {
|
|
||||||
report.errors.push({url: item.url, status: error.response.status});
|
|
||||||
report.setPercentage();
|
|
||||||
}
|
|
||||||
return error.response;
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
await Promise.all(promises);
|
|
||||||
ids.forEach(id => {
|
|
||||||
let report = this.reports.get(id);
|
|
||||||
if (report?.percentage === 100) {
|
|
||||||
report.completed = true;
|
|
||||||
this.sendEmail(report);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private addItemsToQueue(cacheItems: CacheItem[]) {
|
|
||||||
cacheItems.forEach(item => {
|
|
||||||
this.queue.push(item);
|
|
||||||
});
|
|
||||||
if (this.isFinished) {
|
|
||||||
this.processQueue().then(() => {
|
|
||||||
this.isFinished = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sendEmail(report: Report) {
|
|
||||||
let email = Composer.composeEmailToReportCachingProcess(report);
|
|
||||||
axios.post(properties.adminToolsAPIURL + "sendMail/", email).catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function statsToolParser(dataJSONobj: any): any {
|
|
||||||
let RequestInfoObj = Object.assign({});
|
|
||||||
switch (dataJSONobj.library) {
|
|
||||||
case "GoogleCharts":
|
|
||||||
//Pass the Chart library to ChartDataFormatter
|
|
||||||
RequestInfoObj.library = dataJSONobj.library;
|
|
||||||
RequestInfoObj.orderBy = dataJSONobj.orderBy;
|
|
||||||
|
|
||||||
//Create ChartInfo Object Array
|
|
||||||
RequestInfoObj.chartsInfo = [];
|
|
||||||
//Create ChartInfo and pass the Chart data queries to ChartDataFormatter
|
|
||||||
//along with the requested Chart type
|
|
||||||
RequestInfoObj.chartsInfo = dataJSONobj.chartDescription.queriesInfo;
|
|
||||||
break;
|
|
||||||
case "eCharts":
|
|
||||||
//Pass the Chart library to ChartDataFormatter
|
|
||||||
RequestInfoObj.library = dataJSONobj.library;
|
|
||||||
RequestInfoObj.orderBy = dataJSONobj.orderBy;
|
|
||||||
|
|
||||||
//Create ChartInfo Object Array
|
|
||||||
RequestInfoObj.chartsInfo = [];
|
|
||||||
|
|
||||||
//Create ChartInfo and pass the Chart data queries to ChartDataFormatter
|
|
||||||
//along with the requested Chart type
|
|
||||||
for (let index = 0; index < dataJSONobj.chartDescription.queries.length; index++) {
|
|
||||||
let element = dataJSONobj.chartDescription.queries[index];
|
|
||||||
var ChartInfoObj = Object.assign({});
|
|
||||||
|
|
||||||
if (element.type === undefined)
|
|
||||||
ChartInfoObj.type = dataJSONobj.chartDescription.series[index].type;
|
|
||||||
else
|
|
||||||
ChartInfoObj.type = element.type;
|
|
||||||
|
|
||||||
if (element.name === undefined)
|
|
||||||
ChartInfoObj.name = null;
|
|
||||||
else
|
|
||||||
ChartInfoObj.name = element.name;
|
|
||||||
|
|
||||||
ChartInfoObj.query = element.query;
|
|
||||||
RequestInfoObj.chartsInfo.push(ChartInfoObj);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "HighCharts":
|
|
||||||
RequestInfoObj.library = dataJSONobj.library;
|
|
||||||
RequestInfoObj.orderBy = dataJSONobj.orderBy;
|
|
||||||
//Pass the Chart type to ChartDataFormatter
|
|
||||||
var defaultType = dataJSONobj.chartDescription.chart.type;
|
|
||||||
//Create ChartInfo Object Array
|
|
||||||
RequestInfoObj.chartsInfo = [];
|
|
||||||
//Create ChartInfo and pass the Chart data queries to ChartDataFormatter
|
|
||||||
//along with the requested Chart type
|
|
||||||
dataJSONobj.chartDescription.queries.forEach(element => {
|
|
||||||
var ChartInfoObj = Object.assign({});
|
|
||||||
|
|
||||||
if (element.type === undefined)
|
|
||||||
ChartInfoObj.type = defaultType;
|
|
||||||
else
|
|
||||||
ChartInfoObj.type = element.type;
|
|
||||||
|
|
||||||
if (element.name === undefined)
|
|
||||||
ChartInfoObj.name = null;
|
|
||||||
else
|
|
||||||
ChartInfoObj.name = element.name;
|
|
||||||
|
|
||||||
ChartInfoObj.query = element.query;
|
|
||||||
RequestInfoObj.chartsInfo.push(ChartInfoObj);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case "HighMaps":
|
|
||||||
RequestInfoObj.library = dataJSONobj.library;
|
|
||||||
//Create ChartInfo Object Array
|
|
||||||
RequestInfoObj.chartsInfo = [];
|
|
||||||
|
|
||||||
//Create ChartInfo and pass the Chart data queries to ChartDataFormatter
|
|
||||||
dataJSONobj.mapDescription.queries.forEach(element => {
|
|
||||||
var ChartInfoObj = Object.assign({});
|
|
||||||
|
|
||||||
if (element.name === undefined)
|
|
||||||
ChartInfoObj.name = null;
|
|
||||||
else
|
|
||||||
ChartInfoObj.name = element.name;
|
|
||||||
|
|
||||||
ChartInfoObj.query = element.query;
|
|
||||||
RequestInfoObj.chartsInfo.push(ChartInfoObj);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.log("Unsupported Library: " + dataJSONobj.library);
|
|
||||||
}
|
|
||||||
return RequestInfoObj;
|
|
||||||
}
|
|
|
@ -12,4 +12,4 @@ if (properties.environment !== "development") {
|
||||||
}
|
}
|
||||||
|
|
||||||
export { AppServerModule } from './app/app.server.module';
|
export { AppServerModule } from './app/app.server.module';
|
||||||
export { renderModule } from '@angular/platform-server';
|
|
||||||
|
|
|
@ -7,8 +7,6 @@ import {
|
||||||
platformBrowserDynamicTesting
|
platformBrowserDynamicTesting
|
||||||
} from '@angular/platform-browser-dynamic/testing';
|
} from '@angular/platform-browser-dynamic/testing';
|
||||||
|
|
||||||
declare const require: any;
|
|
||||||
|
|
||||||
// First, initialize the Angular testing environment.
|
// First, initialize the Angular testing environment.
|
||||||
getTestBed().initTestEnvironment(
|
getTestBed().initTestEnvironment(
|
||||||
BrowserDynamicTestingModule,
|
BrowserDynamicTestingModule,
|
||||||
|
@ -16,7 +14,3 @@ getTestBed().initTestEnvironment(
|
||||||
teardown: { destroyAfterEach: false }
|
teardown: { destroyAfterEach: false }
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
// Then we find all the tests.
|
|
||||||
const context = require.context('./', true, /\.spec\.ts$/);
|
|
||||||
// And load the modules.
|
|
||||||
context.keys().map(context);
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
"extends": "./tsconfig.app.json",
|
"extends": "./tsconfig.app.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "../out-tsc/app-server",
|
"outDir": "../out-tsc/app-server",
|
||||||
"target": "es2016",
|
|
||||||
"types": [
|
"types": [
|
||||||
"node"
|
"node"
|
||||||
]
|
]
|
||||||
|
|
|
@ -10,13 +10,14 @@
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"importHelpers": true,
|
"importHelpers": true,
|
||||||
"target": "es2020",
|
"target": "ES2022",
|
||||||
"typeRoots": [
|
"typeRoots": [
|
||||||
"node_modules/@types"
|
"node_modules/@types"
|
||||||
],
|
],
|
||||||
"lib": [
|
"lib": [
|
||||||
"es2018",
|
"es2018",
|
||||||
"dom"
|
"dom"
|
||||||
]
|
],
|
||||||
|
"useDefineForClassFields": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue