From b0c69be6ef3e55089d7032f0d1457c874652974f Mon Sep 17 00:00:00 2001 From: Alex Martzios Date: Fri, 8 Mar 2024 12:50:55 +0200 Subject: [PATCH 01/27] [develop | DONE | ADDED] irish-monitor: add new BehaviorSubject for enabling/disabling help-pop-up component on admin and non-admin pages --- dashboard/sharedComponents/sidebar/layout.service.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dashboard/sharedComponents/sidebar/layout.service.ts b/dashboard/sharedComponents/sidebar/layout.service.ts index 17657431..dc515f81 100644 --- a/dashboard/sharedComponents/sidebar/layout.service.ts +++ b/dashboard/sharedComponents/sidebar/layout.service.ts @@ -88,6 +88,10 @@ export class LayoutService { * Handle it manually in the component, it doesn't use data * */ private rootClassSubject: BehaviorSubject = new BehaviorSubject(null); + /** + * Display help pop-up on non-admin pages. (default true for the rest of the pages) + * */ + private hasHelpPopUpSubject: BehaviorSubject = new BehaviorSubject(true); private subscriptions: any[] = []; ngOnDestroy() { @@ -343,4 +347,12 @@ export class LayoutService { this.rootClassSubject.next(value); } } + + get hasHelpPopUp(): Observable { + return this.hasHelpPopUpSubject.asObservable(); + } + + setHasHelpPopUp(value: boolean) { + this.hasHelpPopUpSubject.next(value); + } } From 622459c26c5db0c832e9b159d0558b15b86800c8 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Tue, 12 Mar 2024 19:24:50 +0200 Subject: [PATCH 02/27] [develop]: Helper class: Remove group from mapType. --- login/utils/helper.class.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/login/utils/helper.class.ts b/login/utils/helper.class.ts index 6f2a2951..152cda48 100644 --- a/login/utils/helper.class.ts +++ b/login/utils/helper.class.ts @@ -234,6 +234,7 @@ export class Role { } public static mapType(type: string, communityMap: boolean = true): string { + type = type.replace(this.GROUP, ''); if (type == "ri" && communityMap) { type = "community"; } else if (type == "organization") { From 6b907fe97d765773e2865c748a6edf9fe4c2b866 Mon Sep 17 00:00:00 2001 From: argirok Date: Wed, 13 Mar 2024 12:04:23 +0200 Subject: [PATCH 03/27] [develop | DONE | ADDED] add method for grouped count queries that goes through the cache --- services/searchResearchResults.service.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/services/searchResearchResults.service.ts b/services/searchResearchResults.service.ts index 3e49a7cc..aadcd730 100644 --- a/services/searchResearchResults.service.ts +++ b/services/searchResearchResults.service.ts @@ -133,7 +133,14 @@ export class SearchResearchResultsService { return this.http.get((properties.useLongCache && size == 0 && !params && (!refineQuery || !refineQuery.includes("fq="))) ? (properties.cacheUrl + encodeURIComponent(url)) : url) .pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")])); } + countResults(field:string,value:string): any { + let url = properties.utilsService + "/portals/countResults"; + if (field && value) { + url += "?field=" + encodeURIComponent(field) + "&value="+encodeURIComponent(value); + } + return this.http.get((properties.useLongCache ) ? (properties.cacheUrl + encodeURIComponent(url)) : url); + } searchResultForEntity(resultType: string, params: string, page: number, size: number, properties: EnvProperties): any { let link = properties.searchAPIURLLAst; //let url = link+params+"/"+this.getEntityQueryName(resultType,true)+ "?format=json"; From c64df204052a07c4e061d97492283b775dcc8bb3 Mon Sep 17 00:00:00 2001 From: argirok Date: Thu, 14 Mar 2024 09:28:33 +0200 Subject: [PATCH 04/27] [develop | DONE | ADDED] add orcid-core module, without the routing - use it in other components instead of orcid module --- landingPages/result/resultLanding.module.ts | 4 +- .../searchMyOrcidResults.module.ts | 4 +- orcid/orcid-core.module.ts | 43 +++++++++++++++++++ orcid/orcid.module.ts | 36 ++-------------- utils/result-preview/result-preview.module.ts | 4 +- 5 files changed, 53 insertions(+), 38 deletions(-) create mode 100644 orcid/orcid-core.module.ts diff --git a/landingPages/result/resultLanding.module.ts b/landingPages/result/resultLanding.module.ts index 8554f354..2d7dfc11 100644 --- a/landingPages/result/resultLanding.module.ts +++ b/landingPages/result/resultLanding.module.ts @@ -26,7 +26,6 @@ import {ResultPreviewModule} from "../../utils/result-preview/result-preview.mod import {FeedbackModule} from "../feedback/feedback.module"; import {TabsModule} from "../../utils/tabs/tabs.module"; import {LoadingModule} from "../../utils/loading/loading.module"; -import {OrcidModule} from "../../orcid/orcid.module"; import {IconsModule} from "../../utils/icons/icons.module"; import {IconsService} from "../../utils/icons/icons.service"; import {cite, fire, graph, landmark, link, link_to, quotes, rocket, versions} from "../../utils/icons/icons"; @@ -38,6 +37,7 @@ import {FullScreenModalModule} from "../../utils/modal/full-screen-modal/full-sc import {SafeHtmlPipeModule} from '../../utils/pipes/safeHTMLPipe.module'; import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module"; import {ResultLandingRoutingModule} from "./resultLanding-routing.module"; +import {OrcidCoreModule} from "../../orcid/orcid-core.module"; @NgModule({ imports: [ @@ -47,7 +47,7 @@ import {ResultLandingRoutingModule} from "./resultLanding-routing.module"; AltMetricsModule, Schema2jsonldModule, SEOServiceModule, DeletedByInferenceModule, ShowAuthorsModule, HelperModule, ResultLandingUtilsModule, AlertModalModule, LandingHeaderModule, NoLoadPaging, ResultPreviewModule, FeedbackModule, TabsModule, LoadingModule, - OrcidModule, IconsModule, InputModule, EGIDataTransferModule, RecaptchaModule, + OrcidCoreModule, IconsModule, InputModule, EGIDataTransferModule, RecaptchaModule, SdgFosSuggestModule, FullScreenModalModule, SafeHtmlPipeModule, EntityActionsModule ], declarations: [ diff --git a/orcid/my-orcid-links/searchMyOrcidResults.module.ts b/orcid/my-orcid-links/searchMyOrcidResults.module.ts index 87ce11d0..66cf5358 100644 --- a/orcid/my-orcid-links/searchMyOrcidResults.module.ts +++ b/orcid/my-orcid-links/searchMyOrcidResults.module.ts @@ -6,15 +6,15 @@ import {RouterModule} from '@angular/router'; import {ResultPreviewModule} from "../../utils/result-preview/result-preview.module"; import {ErrorMessagesModule} from "../../utils/errorMessages.module"; import {searcMyOrcidResultsComponent} from "./searchMyOrcidResults.component"; -import {OrcidModule} from "../orcid.module"; import {NoLoadPaging} from "../../searchPages/searchUtils/no-load-paging.module"; import {PagingModule} from "../../utils/paging.module"; +import {OrcidCoreModule} from "../orcid-core.module"; @NgModule({ imports: [ CommonModule, FormsModule, RouterModule, ErrorMessagesModule, - ResultPreviewModule, OrcidModule, NoLoadPaging, PagingModule + ResultPreviewModule, OrcidCoreModule, NoLoadPaging, PagingModule ], declarations: [ searcMyOrcidResultsComponent diff --git a/orcid/orcid-core.module.ts b/orcid/orcid-core.module.ts new file mode 100644 index 00000000..eda20ab1 --- /dev/null +++ b/orcid/orcid-core.module.ts @@ -0,0 +1,43 @@ +import {NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; + +import {RouterModule} from '@angular/router'; + +import {OrcidComponent} from './orcid.component'; +import {OrcidService} from './orcid.service'; +import {OrcidWorkComponent} from './orcid-work.component'; +import {AlertModalModule} from '../utils/modal/alertModal.module'; +import {ResultLandingService} from '../landingPages/result/resultLanding.service'; +import {LoadingModule} from '../utils/loading/loading.module'; +import {ResultLandingUtilsModule} from '../landingPages/landing-utils/resultLandingUtils.module'; +import {IconsModule} from '../utils/icons/icons.module'; +import {IconsService} from "../utils/icons/icons.service"; +import {orcid_add, orcid_bin} from "../utils/icons/icons"; +import {FullScreenModalModule} from "../utils/modal/full-screen-modal/full-screen-modal.module"; +import {LogServiceModule} from "../utils/log/LogService.module"; +import {OrcidRoutingModule} from "./orcid-routing.module"; + +@NgModule({ + imports: [ + CommonModule, RouterModule, AlertModalModule, LoadingModule, ResultLandingUtilsModule, + IconsModule, FullScreenModalModule, LogServiceModule + ], + declarations: [ + OrcidComponent, + OrcidWorkComponent + ], + providers:[ + OrcidService, ResultLandingService + ], + exports: [ + OrcidComponent, + OrcidWorkComponent + ] +}) + + +export class OrcidCoreModule{ + constructor(private iconsService: IconsService) { + this.iconsService.registerIcons([orcid_add, orcid_bin]) + } +} diff --git a/orcid/orcid.module.ts b/orcid/orcid.module.ts index 54bae78b..5743c46a 100644 --- a/orcid/orcid.module.ts +++ b/orcid/orcid.module.ts @@ -1,43 +1,15 @@ import {NgModule} from '@angular/core'; -import {CommonModule} from '@angular/common'; - -import {RouterModule} from '@angular/router'; - -import {OrcidComponent} from './orcid.component'; -import {OrcidService} from './orcid.service'; -import {OrcidWorkComponent} from './orcid-work.component'; -import {AlertModalModule} from '../utils/modal/alertModal.module'; -import {ResultLandingService} from '../landingPages/result/resultLanding.service'; -import {LoadingModule} from '../utils/loading/loading.module'; -import {ResultLandingUtilsModule} from '../landingPages/landing-utils/resultLandingUtils.module'; -import {IconsModule} from '../utils/icons/icons.module'; import {IconsService} from "../utils/icons/icons.service"; import {orcid_add, orcid_bin} from "../utils/icons/icons"; -import {FullScreenModalModule} from "../utils/modal/full-screen-modal/full-screen-modal.module"; -import {LogServiceModule} from "../utils/log/LogService.module"; import {OrcidRoutingModule} from "./orcid-routing.module"; +import {OrcidCoreModule} from "./orcid-core.module"; +import {OrcidComponent} from "./orcid.component"; @NgModule({ - imports: [ - CommonModule, RouterModule, OrcidRoutingModule, AlertModalModule, LoadingModule, ResultLandingUtilsModule, - IconsModule, FullScreenModalModule, LogServiceModule - ], - declarations: [ - OrcidComponent, - OrcidWorkComponent - ], - providers:[ - OrcidService, ResultLandingService - ], - exports: [ - OrcidComponent, - OrcidWorkComponent - ] + imports: [OrcidCoreModule, OrcidRoutingModule], + exports: [OrcidComponent] }) export class OrcidModule{ - constructor(private iconsService: IconsService) { - this.iconsService.registerIcons([orcid_add, orcid_bin]) - } } diff --git a/utils/result-preview/result-preview.module.ts b/utils/result-preview/result-preview.module.ts index 5ad90baf..12726cc6 100644 --- a/utils/result-preview/result-preview.module.ts +++ b/utils/result-preview/result-preview.module.ts @@ -4,15 +4,15 @@ import {ResultPreviewComponent} from "./result-preview.component"; import {RouterModule} from "@angular/router"; import {ShowAuthorsModule} from "../authors/showAuthors.module"; import {ResultLandingUtilsModule} from "../../landingPages/landing-utils/resultLandingUtils.module"; -import {OrcidModule} from "../../orcid/orcid.module"; import {IconsModule} from "../icons/icons.module"; import {IconsService} from "../icons/icons.service"; import {cite, fire, landmark, link, link_to, quotes, rocket} from "../icons/icons"; import {EntityActionsModule} from "../entity-actions/entity-actions.module"; import {EntityMetadataModule} from "../../landingPages/landing-utils/entity-metadata.module"; +import {OrcidCoreModule} from "../../orcid/orcid-core.module"; @NgModule({ - imports: [CommonModule, RouterModule, ShowAuthorsModule, ResultLandingUtilsModule, OrcidModule, IconsModule, EntityActionsModule, EntityMetadataModule], + imports: [CommonModule, RouterModule, ShowAuthorsModule, ResultLandingUtilsModule, OrcidCoreModule, IconsModule, EntityActionsModule, EntityMetadataModule], declarations: [ResultPreviewComponent], exports: [ResultPreviewComponent] }) From ca8b732a640cd222bc6a3a2792a98214dcd8e305 Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Fri, 15 Mar 2024 15:43:58 +0200 Subject: [PATCH 05/27] [develop | DONE | ADDED]: menu.ts: In MenuItem class added field "badge?: string", which is used only in FAIRCORE4EOSC | navigationBar.component.html: Added in menu item (only in no-link parent), to show a badge in FAIRCORE4EOSC. --- sharedComponents/menu.ts | 4 +++- sharedComponents/navigationBar.component.html | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/sharedComponents/menu.ts b/sharedComponents/menu.ts index e3b38e60..b4328834 100644 --- a/sharedComponents/menu.ts +++ b/sharedComponents/menu.ts @@ -23,10 +23,11 @@ export class MenuItem { isFeatured: boolean; isActive: boolean; target: string = "_blank"; + badge?: string = ""; // used only for RDGraph portal (FAIRCORE4EOSC) constructor(id: string, title: string, url: string, route: string, needsAuthorization: boolean, entitiesRequired: string[], routeRequired: string[], params, icon: Icon = null, fragment = null, customClass = null, routeActive = null, - target: string = "_blank", type: string = "internal", isFeatured: boolean = false, items: MenuItem[] = []) { + target: string = "_blank", type: string = "internal", isFeatured: boolean = false, items: MenuItem[] = [], badge: string = "") { this._id = id; this.title = title; this.url = url; @@ -43,6 +44,7 @@ export class MenuItem { this.target = target; this.type = type; this.isFeatured = isFeatured; + this.badge = badge; } public static isTheActiveMenu(menu: MenuItem, currentRoute: any, activeMenuItem: string = ""): boolean { diff --git a/sharedComponents/navigationBar.component.html b/sharedComponents/navigationBar.component.html index 7f502eab..a0147369 100644 --- a/sharedComponents/navigationBar.component.html +++ b/sharedComponents/navigationBar.component.html @@ -41,7 +41,9 @@ {{menu.title}} + [fragment]="menu.fragment"> + {{menu.badge}} + {{menu.title}} {{menu.title}} - {{menu.title}} + + {{menu.badge}} + {{menu.title}}
From 6c4a4d9721030ad43ca7e4112a9bc8c548557123 Mon Sep 17 00:00:00 2001 From: Alex Martzios Date: Tue, 19 Mar 2024 12:55:39 +0200 Subject: [PATCH 06/27] [develop | DONE | ADDED] add new custom classes fo slider-tabs container --- sharedComponents/tabs/slider-tabs.component.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sharedComponents/tabs/slider-tabs.component.ts b/sharedComponents/tabs/slider-tabs.component.ts index d4246f23..84cfbd1c 100644 --- a/sharedComponents/tabs/slider-tabs.component.ts +++ b/sharedComponents/tabs/slider-tabs.component.ts @@ -20,7 +20,7 @@ declare var UIkit; template: `
-
+
    Date: Wed, 27 Mar 2024 16:30:38 +0200 Subject: [PATCH 07/27] [develop | DONE | ADDED]: searchFields.base.ts: Added static "triplet" refine (facet) field "haslicense". --- utils/properties/searchFields.base.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/utils/properties/searchFields.base.ts b/utils/properties/searchFields.base.ts index 79ece5b3..98c6a020 100644 --- a/utils/properties/searchFields.base.ts +++ b/utils/properties/searchFields.base.ts @@ -333,6 +333,14 @@ export class SearchFieldsBase { operator: "pf", equalityOperator: " = ", filterType: "triplet" + }, + ["haslicense"]: { + name: "License", + type: "triplet", + param: "haslicense", + operator: "hl", + equalityOperator: " = ", + filterType: "triplet" } }; @@ -369,6 +377,11 @@ export class SearchFieldsBase { { name: "All", id: "", count: "0" }, { name: "Yes", id: "true", count: "0" }, { name: "No", id: "false", count: "0" } + ], + ["haslicense"]: [ + { name: "All", id: "", count: "0" }, + { name: "Yes", id: "true", count: "0" }, + { name: "No", id: "false", count: "0" } ] }; From cafe0e4926f0d9762cd59a71ce1779743db34771 Mon Sep 17 00:00:00 2001 From: Alex Martzios Date: Thu, 28 Mar 2024 13:07:11 +0200 Subject: [PATCH 08/27] [develop | DONE | ADDED] displayClaims: add bulk delete functionality for claims, change the claims cards to a more compact claims list --- .../displayClaims.component.html | 109 ++++++++++-------- .../displayClaims.component.less | 10 -- .../displayClaims/displayClaims.component.ts | 68 +++++++++-- .../claimEntityFormatter.component.ts | 17 +-- .../projectTitleFormatter.component.ts | 2 +- 5 files changed, 133 insertions(+), 73 deletions(-) diff --git a/claims/claim-utils/displayClaims/displayClaims.component.html b/claims/claim-utils/displayClaims/displayClaims.component.html index bdcc74b3..94034a2e 100644 --- a/claims/claim-utils/displayClaims/displayClaims.component.html +++ b/claims/claim-utils/displayClaims/displayClaims.component.html @@ -56,57 +56,76 @@
    No links found
    -
      -
    • -
      -
      -
      -
      - -
      -
      - available - - pending - -
      -
      -
      - Claimed by: - {{claim.userMail}} + + +
      +
      + +
      + +
      + +
        +
      • +
        + +
        +
        +
        +
        +
        +
        -
        - Claimed date: - {{claim.date}} +
        + available + + pending + +
        +
        +
        + Claimed by: + {{claim.userMail}} +
        +
        + Claimed date: + {{claim.date}} +
        -
        -
        -
        - +
        +
        + +
        +
        +
        +
        -
        -
        -
        -
        - -
      • -
      -
      - -
      +
      + +
      +
    • +
    +
    + +
    +
diff --git a/claims/claim-utils/displayClaims/displayClaims.component.less b/claims/claim-utils/displayClaims/displayClaims.component.less index 0eadec18..e322586c 100644 --- a/claims/claim-utils/displayClaims/displayClaims.component.less +++ b/claims/claim-utils/displayClaims/displayClaims.component.less @@ -4,14 +4,4 @@ position: relative; padding: 0 20px; height: 100%; - - &::before { - content: ''; - position: absolute; - top: 0; - left: 50%; - right: 0; - bottom: 0; - border-left: @global-border-width solid @global-border; - } } diff --git a/claims/claim-utils/displayClaims/displayClaims.component.ts b/claims/claim-utils/displayClaims/displayClaims.component.ts index 9e5ccf97..8f24cf4d 100644 --- a/claims/claim-utils/displayClaims/displayClaims.component.ts +++ b/claims/claim-utils/displayClaims/displayClaims.component.ts @@ -52,6 +52,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy { lastIndexDate = null; public filterForm: FormGroup; public entities: string[] = []; + selected = []; allOptions: Option[] = [ {label: OpenaireEntities.PUBLICATIONS, value: "publication"}, @@ -310,23 +311,34 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy { } isSelected(value: string) { - return this.filterForm && this.filterForm.get('entities').value.find(entity => entity === value) + return this.filterForm && this.filterForm.get('entities').value.find(entity => entity === value); } - deleteOpen(index: number) { + deleteOpen(index: number = null) { this.index = index; this.deleteModal.alertTitle = 'Delete Confirmation'; - this.deleteModal.message = 'Are you sure you want to delete this link?'; + this.deleteModal.message = 'Are you sure you want to delete ' + (this.index != null ? '1' : this.selected.length) + ' link(s)?'; this.deleteModal.okButtonText = 'Yes'; this.deleteModal.open(); } delete() { - this.subscriptions.push(this._claimService.deleteBulk([this.claims[this.index].id], this.properties.claimsAPIURL).subscribe( + let claimsToBeDeleted = ((this.index != null) ? [this.claims[this.index].id] : this.selected.map(claim => claim.id)); + console.log(claimsToBeDeleted); + this.subscriptions.push(this._claimService.deleteBulk(claimsToBeDeleted, this.properties.claimsAPIURL).subscribe( res => { - this.claims.splice(this.index, 1); - this.resultsNum = this.resultsNum - 1; - NotificationHandler.rise('Link has been deleted successfully'); + if (this.index != null) { + this.claims.splice(this.index, 1); + this.resultsNum = this.resultsNum - 1; + NotificationHandler.rise('Link has been deleted successfully'); + } else { + claimsToBeDeleted.forEach(claimId => { + this.claims.splice(this.claims.findIndex((id) => id == claimId), 1); + }); + this.resultsNum = this.resultsNum - claimsToBeDeleted.length; + NotificationHandler.rise(claimsToBeDeleted.length + ' links have been deleted successfully'); + } + this.selected = []; let goToPage = this.page; if (this.totalPages(this.resultsNum) < this.page && this.page > 0) { goToPage = this.page - 1; @@ -334,7 +346,8 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy { this.goTo(goToPage); }, err => { this.handleErrors(err, "Error deleting claim with id: " + this.claims[this.index].id); - })); + } + )); } pageChange($event) { @@ -362,7 +375,44 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy { } return totalPages; } - + + selectClaim(item: any, event) { + let value = event.currentTarget.checked; + if (value) { + this.selected.push(item); + } else { + for (var _i = 0; _i < this.selected.length; _i++) { + let claim = this.selected[_i]; + if (claim['id'] == item.id) { + this.selected.splice(_i, 1); + } + } + } + } + + selectAll(event) { + let value = event.currentTarget.checked; + if (value) { + this.selected = []; + for (let _i = 0; _i < this.claims.length; _i++) { + let claim = this.claims[_i]; + this.selected.push(claim); + } + } else { + this.selected = []; + } + } + + isSelectedClaim(id: string) { + for (let _i = 0; _i < this.selected.length; _i++) { + let claim = this.selected[_i]; + if (claim['id'] == id) { + return true; + } + } + return false; + } + private updateDescription(description: string) { this._meta.updateTag({content: description}, "name='description'"); this._meta.updateTag({content: description}, "property='og:description'"); diff --git a/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts b/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts index 6102d684..547e4c16 100644 --- a/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts +++ b/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts @@ -15,21 +15,22 @@ import {StringUtils} from "../../../utils/string-utils.class";
{{getEntityName(type)}}
-
- Link to: +
+ Link to:
-
- Link to: +
+ Link to:
-
- Link to: - {{entity.title}} +
+ Link to: +
+ {{entity.title}} +
` }) diff --git a/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts b/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts index 92557d9a..14ee0e60 100644 --- a/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts +++ b/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts @@ -20,7 +20,7 @@ import {properties} from "../../../../../environments/environment"; - Funder: {{project['funderName']}} + Funder: {{project['funderName']}} ` }) From 894667955c788cc72db30ce68fa284b4fd02bd45 Mon Sep 17 00:00:00 2001 From: Alex Martzios Date: Thu, 28 Mar 2024 13:22:21 +0200 Subject: [PATCH 09/27] [develop | DONE | ADDED] slider-tabs component: add condition to disable slider-arrows if isServer is true --- sharedComponents/tabs/slider-tabs.component.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sharedComponents/tabs/slider-tabs.component.ts b/sharedComponents/tabs/slider-tabs.component.ts index 84cfbd1c..666f90a2 100644 --- a/sharedComponents/tabs/slider-tabs.component.ts +++ b/sharedComponents/tabs/slider-tabs.component.ts @@ -6,11 +6,14 @@ import { ElementRef, EventEmitter, Input, OnDestroy, Output, QueryList, - ViewChild + ViewChild, + Inject, + PLATFORM_ID } from "@angular/core"; import {SliderTabComponent} from "./slider-tab.component"; import {ActivatedRoute, Router} from "@angular/router"; import {Subscription} from "rxjs"; +import {isPlatformServer} from "@angular/common"; import Timeout = NodeJS.Timeout; declare var UIkit; @@ -78,8 +81,10 @@ declare var UIkit;
- - + + + +
`, }) @@ -143,10 +148,13 @@ export class SliderTabsComponent implements AfterViewInit, OnDestroy { private subscriptions: any[] = []; private observer: IntersectionObserver; private timeout: Timeout; + isServer: boolean; constructor(private route: ActivatedRoute, private router: Router, - private cdr: ChangeDetectorRef) { + private cdr: ChangeDetectorRef, + @Inject(PLATFORM_ID) private platform: any) { + this.isServer = isPlatformServer(this.platform); } ngAfterViewInit() { From 0c7539462183f2716718afdc79f5db12ed581ba2 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Mon, 1 Apr 2024 01:16:31 +0300 Subject: [PATCH 10/27] [develop | FIXED | CHANGED]: Add stakeholder in export indicators file and import base on this stakeholder. --- monitor-admin/topic/indicators.component.html | 49 -------- monitor-admin/topic/indicators.component.ts | 105 +++++------------- 2 files changed, 30 insertions(+), 124 deletions(-) diff --git a/monitor-admin/topic/indicators.component.html b/monitor-admin/topic/indicators.component.html index 05144592..e4e84099 100644 --- a/monitor-admin/topic/indicators.component.html +++ b/monitor-admin/topic/indicators.component.html @@ -14,16 +14,6 @@ (click)="deleteSectionOpen(number, i, 'number', 'delete')"> - - - - - - - - - -
@@ -113,16 +103,6 @@ (click)="deleteSectionOpen(chart, i, 'chart', 'delete')"> - - - - - - - - - -
- @@ -440,8 +419,6 @@ - -
@@ -462,25 +439,10 @@
Indicators of all profiles based on this default indicator, will be deleted as well.
- - - Are you sure you want to proceed?
-
@@ -490,20 +452,9 @@
Sections of all profiles based on this default section and their contents, will be deleted as well.
- - - Are you sure you want to proceed?
-
diff --git a/monitor-admin/topic/indicators.component.ts b/monitor-admin/topic/indicators.component.ts index 30343944..1abcfa4d 100644 --- a/monitor-admin/topic/indicators.component.ts +++ b/monitor-admin/topic/indicators.component.ts @@ -504,16 +504,6 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.numberIndicatorPaths.at(index).get('result').setValue(null); if (this.numberIndicatorPaths.at(index).get('url').valid) { let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(value), value, this.stakeholder, this.numberIndicatorPaths.at(index).get('jsonPath').value, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(value))); - if (!this.isStakeholderParametersValid(indicatorPath)) { - // default profile - if (this.stakeholder.defaultId == null) { - this.urlParameterizedMessage = "This indicator couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly." - } else { - this.urlParameterizedMessage = "This indicator couldn't be generated properly. Please make sure chart data is for the current stakeholder." - } - } else { - this.urlParameterizedMessage = null; - } this.checkForSchemaEnhancements(this.numberIndicatorPaths.at(index).get('url').value); if (this.indicator.indicatorPaths[index]) { this.indicator.indicatorPaths[index] = indicatorPath; @@ -574,16 +564,6 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.urlSubscriptions.push(this.chartIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => { if (this.chartIndicatorPaths.at(index).get('url').valid) { let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(value), value, this.chartIndicatorPaths.at(index).get('type').value, this.stakeholder); - if (!this.isStakeholderParametersValid(indicatorPath)) { - // default profile - if (this.stakeholder.defaultId == null) { - this.urlParameterizedMessage = "This chart couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly." - } else { - this.urlParameterizedMessage = "This chart couldn't be generated properly. Please make sure chart data is for the current stakeholder." - } - } else { - this.urlParameterizedMessage = null; - } this.checkForSchemaEnhancements(this.chartIndicatorPaths.at(index).get('url').value); (this.chartIndicatorPaths.at(index) as UntypedFormGroup).get('type').setValue(indicatorPath.type); (this.chartIndicatorPaths.at(index) as UntypedFormGroup).setControl('parameters', this.getParametersAsFormArray(indicatorPath)); @@ -601,12 +581,6 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } } - private isStakeholderParametersValid(indicatorPath: IndicatorPath) { - return !((indicatorPath.chartObject && Object.keys(indicatorPath.parameters).indexOf("index_id") == -1 && Object.keys(indicatorPath.parameters).indexOf("index_name") == -1 && Object.keys(indicatorPath.parameters).indexOf("index_shortName") == -1) - || (!indicatorPath.chartObject && indicatorPath.url.indexOf("index_id") == -1 && indicatorPath.url.indexOf("index_name") == -1 && (indicatorPath.url).indexOf("index_shortName") == -1)); - - } - private getJsonPathAsFormArray(indicatorPath: IndicatorPath): UntypedFormArray { let jsonPath = this.fb.array([]); if (indicatorPath.jsonPath) { @@ -1159,24 +1133,6 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple })); } - // deleteNumberSectionOpen(section: Section, index: number) { - // this.section = section; - // this.index = index; - // this.deleteNumberSectionModal.alertTitle = 'Delete Section'; - // this.deleteNumberSectionModal.cancelButtonText = 'No'; - // this.deleteNumberSectionModal.okButtonText = 'Yes'; - // this.deleteNumberSectionModal.open(); - // } - // - // deleteChartSectionOpen(section: Section, index: number) { - // this.section = section; - // this.index = index; - // this.deleteChartSectionModal.alertTitle = 'Delete Section'; - // this.deleteChartSectionModal.cancelButtonText = 'No'; - // this.deleteChartSectionModal.okButtonText = 'Yes'; - // this.deleteChartSectionModal.open(); - // } - deleteSectionOpen(section: Section, index: number, type: IndicatorType, childrenAction: string = null) { if (!this.editing && !section.defaultId) { this.sectionTypeToDelete = type; @@ -1256,11 +1212,20 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple return charts; } - importIndicatorsAndSave(charts: any[]) { + importIndicatorsAndSave(stakeholder: Stakeholder, charts: any[]) { let sectionsToSave: Section[] = []; let countIndicators = 0; + if(stakeholder.type !== this.stakeholder.type) { + UIkit.notification("The type of this profile is not the same with the file's one!", { + status: 'warning', + timeout: 6000, + pos: 'bottom-right' + }); + this.editing = false; + this.importLoading = false; + return; + } // name description additionalDescription, height, width, visibility - let noValidParams = 0; let duplicates = 0; charts = this.migrateFromOldImportJsonFile(charts); for (let chart of charts) { @@ -1296,7 +1261,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } if (chart.type == "chart") { - indicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(chart.url), chart.url, chart.type, this.stakeholder); + indicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(chart.url), chart.url, chart.type, stakeholder); for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].charts) { for (let chart of section.indicators) { if (JSON.stringify(chart.indicatorPaths[0].chartObject) == JSON.stringify(indicatorPath.chartObject)) { @@ -1304,10 +1269,9 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple exists = true; } } - } } else if (chart.type == "number") { - indicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(chart.url), chart.url, this.stakeholder, + indicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(chart.url), chart.url, stakeholder, chart.jsonPath, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(chart.url))); for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].numbers) { for (let chart of section.indicators) { @@ -1316,20 +1280,14 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple exists = true; } } - } } - if (!this.isStakeholderParametersValid(indicatorPath)) { - noValidParams++; - } if (!exists) { let i: Indicator = new Indicator(chart.name, chart.description, chart.additionalDescription, chart.type, chart.width, chart.height, this.showVisibility?"RESTRICTED":this.stakeholderUtils.defaultValue(this.stakeholderUtils.visibilities), [indicatorPath]); sectionsToSave[chart['sectionIndex']].indicators.push(i); countIndicators++; } - } - if (duplicates > 0) { UIkit.notification(duplicates + " urls already exist and will not be imported!", { status: 'warning', @@ -1337,19 +1295,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple pos: 'bottom-right' }); } - if (noValidParams > 0 && !(this.stakeholder.type == 'country')) { - let noValidMessage = "Some indicators couldn't be generated properly. Please make sure chart data is for the current stakeholder."; - if (this.stakeholder.defaultId == null) { - noValidMessage = "Some indicators couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly."; - } - UIkit.notification(noValidMessage, { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - this.importLoading = false; - } else if (sectionsToSave.length > 0 && countIndicators > 0) { + if (sectionsToSave.length > 0 && countIndicators > 0) { this.saveIndicators(sectionsToSave.filter(section => !!section)); } if (sectionsToSave.length == 0 || countIndicators == 0) { @@ -1408,8 +1354,11 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple let topic = this.stakeholder ? this.stakeholder.topics[this.topicIndex] : null; let category = topic ? topic.categories[this.categoryIndex] : null; let subCategory = category ? category.subCategories[subcategoryIndex] : null; - - var jsonFileUrl = window.URL.createObjectURL(new Blob([JSON.stringify(indicators)], {type: 'application/json'})); + let json = { + stakeholder: this.stakeholder, + indicators: indicators + } + var jsonFileUrl = window.URL.createObjectURL(new Blob([JSON.stringify(json)], {type: 'application/json'})); var a = window.document.createElement('a'); window.document.body.appendChild(a); a.setAttribute('style', 'display: none'); @@ -1456,11 +1405,17 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } this.makeFileRequest(this.properties.utilsService + '/upload?type=json', [], this.filesToUpload).then(async (result: string) => { - - let json_result = JSON.parse(result); - + let json = JSON.parse(result); // validate file - if (!json_result || json_result.length == 0) { + if(json && Array.isArray(json)) { + UIkit.notification("This file is not supported any more. Please export indicators and try again!", { + status: 'danger', + timeout: 6000, + pos: 'bottom-right' + }); + this.editing = false; + this.importLoading = false; + } else if (!json || json?.indicators.length == 0) { UIkit.notification("Importing file is empty", { status: 'danger', timeout: 6000, @@ -1469,7 +1424,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.editing = false; this.importLoading = false; } else { - this.importIndicatorsAndSave(json_result); + this.importIndicatorsAndSave(json.stakeholder, json.indicators); } }, (error) => { console.error("Error importing files", error); From b34f42326ca8069b6ade0e1934c7e7cd021112cb Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Mon, 1 Apr 2024 18:16:21 +0300 Subject: [PATCH 11/27] [develop | ADDED]: Add loading in import indicators in order to avoid any actions during this process --- monitor-admin/topic/indicators.component.html | 9 ++-- monitor-admin/topic/indicators.component.ts | 45 ++++++++----------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/monitor-admin/topic/indicators.component.html b/monitor-admin/topic/indicators.component.html index e4e84099..b9bce2df 100644 --- a/monitor-admin/topic/indicators.component.html +++ b/monitor-admin/topic/indicators.component.html @@ -198,13 +198,16 @@
+
+ +
-
- -
+
+ +
diff --git a/monitor-admin/topic/indicators.component.ts b/monitor-admin/topic/indicators.component.ts index 1abcfa4d..ab491a54 100644 --- a/monitor-admin/topic/indicators.component.ts +++ b/monitor-admin/topic/indicators.component.ts @@ -86,8 +86,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple public safeUrls: Map = new Map([]); public numberResponses: Map = new Map(); public numberResults: Map = new Map(); - /** Import / Export Indicators */ - importLoading: boolean = false; + public loading: boolean = false; @ViewChild('editChartModal', {static: true}) editChartModal: AlertModal; @ViewChild('editNumberModal', {static: true}) editNumberModal: AlertModal; @ViewChild('deleteModal', {static: true}) deleteModal: AlertModal; @@ -354,7 +353,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple return this.stakeholder && this.stakeholder.topics[this.topicIndex] && this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]; + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex] && !this.loading; } public get numberIndicatorPaths(): UntypedFormArray { @@ -874,19 +873,22 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple }); } } - this.editing = false; - this.importLoading = false; + this.finish(); NotificationHandler.rise('Indicators have been imported successfully!'); }, error => { this.chartIndicatorFb = null; NotificationHandler.rise('An error has occurred. Please try again later', 'danger'); - this.editing = false; - this.importLoading = false; + this.finish(); })); } + finish() { + this.editing = false; + this.loading = false; + } + reorderIndicators(sectionId: string, type: IndicatorType, reorder: Reorder) { this.editing = true; let path = [ @@ -1221,8 +1223,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); return; } // name description additionalDescription, height, width, visibility @@ -1255,8 +1256,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); break; } @@ -1304,8 +1304,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); } } @@ -1367,14 +1366,13 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple a.click(); window.URL.revokeObjectURL(jsonFileUrl); a.remove(); // remove the element - - this.editing = false; + this.finish(); } fileChangeEvent(fileInput: any, index) { this.index = index; this.editing = true; - this.importLoading = true; + this.loading = true; this.filesToUpload = >fileInput.target.files; this.upload(); } @@ -1387,8 +1385,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); return; } else { if (this.filesToUpload[0].name.indexOf(".json") == -1 || (this.filesToUpload[0].type != "application/json")) { @@ -1398,8 +1395,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); return; } } @@ -1413,16 +1409,14 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); } else if (!json || json?.indicators.length == 0) { UIkit.notification("Importing file is empty", { status: 'danger', timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); } else { this.importIndicatorsAndSave(json.stakeholder, json.indicators); } @@ -1433,8 +1427,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); }); } From 828dfc0671dc58977ef30a641cbd7fe7f94c0eb5 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Mon, 1 Apr 2024 18:56:26 +0300 Subject: [PATCH 12/27] [develop]: Remove topics from exported file in export indicators. --- monitor-admin/topic/indicators.component.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/monitor-admin/topic/indicators.component.ts b/monitor-admin/topic/indicators.component.ts index ab491a54..46119354 100644 --- a/monitor-admin/topic/indicators.component.ts +++ b/monitor-admin/topic/indicators.component.ts @@ -1354,9 +1354,10 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple let category = topic ? topic.categories[this.categoryIndex] : null; let subCategory = category ? category.subCategories[subcategoryIndex] : null; let json = { - stakeholder: this.stakeholder, + stakeholder: HelperFunctions.copy(this.stakeholder), indicators: indicators } + delete json.stakeholder.topics; var jsonFileUrl = window.URL.createObjectURL(new Blob([JSON.stringify(json)], {type: 'application/json'})); var a = window.document.createElement('a'); window.document.body.appendChild(a); From 78d262dd3b67ceb022cf9a3e5135bcf8466c7f1c Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Tue, 2 Apr 2024 10:59:33 +0300 Subject: [PATCH 13/27] [develop | DONE | ADDED]: Added search organizations by PID (ror, isni, wikidata, fundRef). 1. string-utils.class.ts: Added methods "isValidRor()", "isValidIsni()", "isValidWikidata()", "isValidFundRef()" and cases for these new identifiers. 2. newSearchPage.component.ts: In method "createKeywordQuery()", check for PIDs also for organizations entity. 3. environment.ts: Updated property "fundRefURL" to "https://data.crossref.org/fundingdata/funder/" (old: https://api.crossref.org/funders/). --- .../searchUtils/newSearchPage.component.ts | 2 +- utils/properties/environments/environment.ts | 2 +- utils/string-utils.class.ts | 37 +++++++++++++++++-- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/searchPages/searchUtils/newSearchPage.component.ts b/searchPages/searchUtils/newSearchPage.component.ts index cf9f105a..e8447acb 100644 --- a/searchPages/searchUtils/newSearchPage.component.ts +++ b/searchPages/searchUtils/newSearchPage.component.ts @@ -1085,7 +1085,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { let params = ""; let doisParams = ""; var DOIs: Identifier[] = Identifier.getIdentifiersFromString(value); - if ((entityType == 'publication' || entityType == 'dataset' || entityType == 'software' || entityType == 'other' || entityType == "result" || entityType == "dataprovider" || entityType == "service")) { + if ((entityType == 'publication' || entityType == 'dataset' || entityType == 'software' || entityType == 'other' || entityType == "result" || entityType == "dataprovider" || entityType == "service" || entityType == "organization")) { for (let identifier of DOIs) { // console.log(identifier) // pidclassid exact \"doi\" and pid exact \"10.1016/j.nima.2015.11.134\" diff --git a/utils/properties/environments/environment.ts b/utils/properties/environments/environment.ts index fb86e5d4..283a1295 100644 --- a/utils/properties/environments/environment.ts +++ b/utils/properties/environments/environment.ts @@ -23,7 +23,7 @@ export let common: EnvProperties = { rorURL: "https://ror.org/", isniURL: "https://isni.org/isni/", wikiDataURL: "https://www.wikidata.org/wiki/", - fundRefURL: "https://api.crossref.org/funders/", + fundRefURL: "https://data.crossref.org/fundingdata/funder/", fairSharingURL: "https://fairsharing.org/", eoscMarketplaceURL: "https://marketplace.eosc-portal.eu/services/", sherpaURL: "http://sherpa.ac.uk/romeo/issn/", diff --git a/utils/string-utils.class.ts b/utils/string-utils.class.ts index cbce9848..3ccf6e6b 100644 --- a/utils/string-utils.class.ts +++ b/utils/string-utils.class.ts @@ -150,7 +150,7 @@ export class DOI { } export class Identifier { - class: "doi" | "pmc" | "pmid" | "handle" | "ORCID" | "re3data" | "swhid" = null; + class: "doi" | "pmc" | "pmid" | "handle" | "ORCID" | "re3data" | "swhid" | "ror" | "wikidata" | "fundref" | "isni" = null; id: string; public static getDOIsFromString(str: string): string[] { @@ -205,14 +205,22 @@ export class Identifier { return {"class": "re3data", "id": pid}; } else if (Identifier.isValidSwhId(pid)) { return {"class": "swhid", "id": pid}; + } else if (Identifier.isValidRor(pid)) { + return {"class": "ror", "id": pid}; + } else if (Identifier.isValidFundRef(pid)) { + return {"class": "fundref", "id": pid}; + } else if (Identifier.isValidWikidata(pid)) { + return {"class": "wikidata", "id": pid}; + } else if (Identifier.isValidIsni(pid)) { + return {"class": "isni", "id": pid}; } //set it as a doi, to catch the case that doi has not valid format return (strict?null:{"class": "doi", "id": pid}); } public static getPIDFromIdentifiers(identifiers: Map): Identifier { - let classes:string [] = ["doi", "handle", "pmc", "pmid", "re3data", "swhid"]; - if(identifiers) { + let classes:string [] = ["doi", "handle", "pmc", "pmid", "re3data", "swhid", "ror", "wikidata", "fundref", "isni"]; + if(identifiers && identifiers.size > 0) { for (let cl of classes) { if (identifiers.get(cl)) { for (let pid of identifiers.get(cl)) { @@ -258,6 +266,7 @@ export class Identifier { } public static isValidHANDLE(str: string): boolean { + // let exp = /\b[0-9a-zA-Z-]*\/[0-9a-zA-Z-]*$/g; // resolve with url - need to add method for raw value let exp = /^[0-9a-zA-Z-]*\/[0-9a-zA-Z-]*$/g; return str.match(exp) != null; } @@ -272,6 +281,28 @@ export class Identifier { let exp = /swh:1:snp:[0-9a-f]{40}/g; return str.match(exp) != null; } + + public static isValidRor(str: string): boolean { + let exp = /0[a-z|0-9]{6}[0-9]{2}\b/g; + return str.match(exp) != null; + } + + public static isValidIsni(str: string): boolean { + let exp = /^[0]{7}[0-9]{8}[0-9X]$/g; + return str.match(exp) != null; + } + + public static isValidWikidata(str: string): boolean { + let exp = /^Q\d+$/g; + return str.match(exp) != null; + } + + public static isValidFundRef(str: string): boolean { + // let exp = /aaa/g; + let exp = /^[1-9]\d+$/g; + return str.match(exp) != null; + } + } export class StringUtils { From 18791ec9d22d3f30dd895e2e090d154b9e7b75fb Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Tue, 2 Apr 2024 13:33:23 +0300 Subject: [PATCH 14/27] [develop | DONE | ADDED]: searchFields.base.ts: Added "pid" field in ORGANIZATION_ADVANCED_FIELDS. --- utils/properties/searchFields.base.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils/properties/searchFields.base.ts b/utils/properties/searchFields.base.ts index 98c6a020..1813b1a2 100644 --- a/utils/properties/searchFields.base.ts +++ b/utils/properties/searchFields.base.ts @@ -798,7 +798,7 @@ export class SearchFieldsBase { //ORGANIZATION public ORGANIZATION_REFINE_FIELDS: string[] = ["country"] - public ORGANIZATION_ADVANCED_FIELDS: string[] = ["q", "organizationlegalname", "organizationlegalshortname", "country"]; + public ORGANIZATION_ADVANCED_FIELDS: string[] = ["q", "organizationlegalname", "organizationlegalshortname", "country", "pid"]; public ORGANIZATION_FIELDS: { [key: string]: FieldDetails } = { ["q"]: {name: "Any field", type: "keyword", param: "q", operator: "op", equalityOperator: "=", filterType: null}, @@ -826,6 +826,7 @@ export class SearchFieldsBase { equalityOperator: " exact ", filterType: "checkbox" }, + ["pid"]: {name: "PID", type: "keyword", param: "pid", operator: "pd", equalityOperator: " exact ", filterType: null} }; // public ORGANIZATION_INDEX:string[] = ["organizationcountryname"]//,"organizationeclegalbody"]; // public ADVANCED_SEARCH_ORGANIZATION_PARAM:string[] = ["q","contenttype","compatibility","country","type"]; From 07569f24e16f1818742c41aacd86a6a76ac920af Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Wed, 3 Apr 2024 16:16:09 +0300 Subject: [PATCH 15/27] [develop | DONE | FIXED]: resultLanding.component.html & searchResult.component.ts: Added checks for ORCID also for properties.dashboard == "irish". --- landingPages/result/resultLanding.component.html | 6 ++++-- searchPages/searchUtils/searchResult.component.ts | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/landingPages/result/resultLanding.component.html b/landingPages/result/resultLanding.component.html index 3a2de7e2..d99ba7b3 100644 --- a/landingPages/result/resultLanding.component.html +++ b/landingPages/result/resultLanding.component.html @@ -79,7 +79,8 @@ [type]="resultLandingInfo.resultType" [result]="resultLandingInfo" [id]="resultLandingInfo.objIdentifier"> -
@@ -544,7 +545,8 @@

- +
0 && (this.type == "result" || this.type == "publication" || this.type == "dataset" || this.type == "software" || this.type == "other") ) { From dcfc6b0b6a288d5f944efb63f51d8e6d11e5df76 Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Thu, 4 Apr 2024 16:10:08 +0300 Subject: [PATCH 16/27] [develop | DONE | CHANGED]: searchFields.base.ts: Replace in ORGANIZATION_REFINE_FIELDS and ORGANIZATION_ADVANCED_FIELDS field "country" with "countrynojurisdiction". --- utils/properties/searchFields.base.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/properties/searchFields.base.ts b/utils/properties/searchFields.base.ts index 1813b1a2..a029a42e 100644 --- a/utils/properties/searchFields.base.ts +++ b/utils/properties/searchFields.base.ts @@ -797,8 +797,8 @@ export class SearchFieldsBase { //ORGANIZATION - public ORGANIZATION_REFINE_FIELDS: string[] = ["country"] - public ORGANIZATION_ADVANCED_FIELDS: string[] = ["q", "organizationlegalname", "organizationlegalshortname", "country", "pid"]; + public ORGANIZATION_REFINE_FIELDS: string[] = ["countrynojurisdiction"] + public ORGANIZATION_ADVANCED_FIELDS: string[] = ["q", "organizationlegalname", "organizationlegalshortname", "countrynojurisdiction", "pid"]; public ORGANIZATION_FIELDS: { [key: string]: FieldDetails } = { ["q"]: {name: "Any field", type: "keyword", param: "q", operator: "op", equalityOperator: "=", filterType: null}, @@ -818,7 +818,7 @@ export class SearchFieldsBase { equalityOperator: "=", filterType: null }, - ["country"]: { + ["countrynojurisdiction"]: { name: "Country", type: "vocabulary", param: "country", @@ -962,7 +962,7 @@ export class SearchFieldsBase { return "and"; } else if (fieldId == "instancetypename" || fieldId == "eoscdatasourcetype" || fieldId == "resultlanguagename" || fieldId == "datasourceodlanguages" - || fieldId == "datasourcecompatibilityname" || fieldId == "country" || fieldId == "datasourceodcontenttypes" + || fieldId == "datasourcecompatibilityname" || fieldId == "country" || fieldId == "countrynojurisdiction" || fieldId == "datasourceodcontenttypes" || fieldId == "resulthostingdatasource" || fieldId == "collectedfrom") { return "or"; } From c351349f8ee3a130c56dc72b17159f07460c108e Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Thu, 4 Apr 2024 17:13:56 +0300 Subject: [PATCH 17/27] [develop | DONE | FIXED] newSearchPage.component.html: Added checks, not to show "Filters" column in the search pages, when there are no filters. --- searchPages/searchUtils/newSearchPage.component.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/searchPages/searchUtils/newSearchPage.component.html b/searchPages/searchUtils/newSearchPage.component.html index f9143437..ab005f85 100644 --- a/searchPages/searchUtils/newSearchPage.component.html +++ b/searchPages/searchUtils/newSearchPage.component.html @@ -288,7 +288,9 @@
-
0) || (staticFilters && staticFilters.length > 0) + || (rangeFilters && rangeFilters.length > 0) || (filters && filters.length > 0))) + && (results.length > 0 || (searchUtils.refineStatus == errorCodes.LOADING && searchUtils.status != errorCodes.LOADING) || (!hideFilters && (existingFiltersWithValues > 0 || (selectedRangeFilters + selectedFilters + selectedTypesNum) > 0))) " class="uk-width-1-4@m search-filters"> From d63092cd9e48b10d130eb52fccfad945e9d785ba Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Fri, 5 Apr 2024 10:57:39 +0300 Subject: [PATCH 18/27] [new-order | DONE]: Add new move indicator method when an indicator moved to another section --- monitor-admin/topic/indicators.component.html | 14 ---- monitor-admin/topic/indicators.component.ts | 67 +++++++++++-------- monitor/services/stakeholder.service.ts | 31 +++++---- 3 files changed, 57 insertions(+), 55 deletions(-) diff --git a/monitor-admin/topic/indicators.component.html b/monitor-admin/topic/indicators.component.html index b9bce2df..1f68e246 100644 --- a/monitor-admin/topic/indicators.component.html +++ b/monitor-admin/topic/indicators.component.html @@ -236,13 +236,6 @@
-
-
- There are schema enhancements that can be applied in this query.Apply - now -
-
@@ -373,13 +366,6 @@
-
-
- There are schema enhancements that can be applied in this query. Apply - now -
-
= new BehaviorSubject(null); /** Caches */ public safeUrls: Map = new Map([]); public numberResponses: Map = new Map(); @@ -94,8 +96,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple public sectionTypeToDelete: string; public sectionChildrenActionOnDelete: string; public indicatorChildrenActionOnDelete: string; - urlParameterizedMessage = null; - showCheckForSchemaEnhancements: boolean = false; + public urlParameterizedMessage = null; private notification: Notification; @ViewChild('editNumberNotify', {static: true}) editNumberNotify: NotifyFormComponent; @ViewChild('editChartNotify', {static: true}) editChartNotify: NotifyFormComponent; @@ -124,7 +125,6 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple private notificationService: NotificationService, private fb: UntypedFormBuilder, protected _router: Router, - private cdr: ChangeDetectorRef, private sanitizer: DomSanitizer) { super() this.filesToUpload = []; @@ -186,7 +186,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } }); if (document !== undefined) { - let callback = (list, type: IndicatorType, action: 'moved' | 'added' | 'removed'): void => { + let callback = (list): string[] => { let items: HTMLCollection = list.current.children; let reordered = []; for (let i = 0; i < items.length; i++) { @@ -194,12 +194,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple reordered.push(items.item(i).id); } } - let reorder: Reorder = { - action: action, - target: list.detail[1].id, - ids: reordered - } - this.reorderIndicators(list.current.id.toString().split('-')[1], type, reorder); + return reordered; }; this.numbers.forEach((section) => { this.subscriptions.push(UIkit.util.on(document, 'start', '#number-' + section._id, (): void => { @@ -209,24 +204,32 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.dragging = false; })); this.subscriptions.push(UIkit.util.on(document, 'moved', '#number-' + section._id, (list): void => { - callback(list, "number", 'moved'); + this.reorderIndicators(section._id, 'number', callback(list)); })); this.subscriptions.push(UIkit.util.on(document, 'added', '#number-' + section._id, (list): void => { - callback(list, "number", 'added'); + this.to.next({id: section._id, indicators: callback(list)}); })); this.subscriptions.push(UIkit.util.on(document, 'removed', '#number-' + section._id, (list): void => { - callback(list, "number", 'removed'); + let sub = this.to.asObservable().subscribe(to => { + if(to) { + let from: SectionInfo = {id: section._id, indicators: callback(list)}; + this.moveIndicator({target: list.detail[1].id, from: from, to: to}); + setTimeout(() => { + sub.unsubscribe(); + }) + } + }) })); }); this.charts.forEach((section) => { this.subscriptions.push(UIkit.util.on(document, 'moved', '#chart-' + section._id, (list): void => { - callback(list, "chart", 'moved'); + this.reorderIndicators(section._id, 'chart', callback(list)); })); this.subscriptions.push(UIkit.util.on(document, 'added', '#chart-' + section._id, (list): void => { - callback(list, "chart", 'added'); + //callback(list, "chart", 'added'); })); this.subscriptions.push(UIkit.util.on(document, 'removed', '#chart-' + section._id, (list): void => { - callback(list, "chart", 'removed'); + // callback(list, "chart", 'removed'); })); }); } @@ -496,14 +499,12 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple let index = this.numberIndicatorPaths.length - 1; if (this.numberIndicatorPaths.at(index).get('url').valid) { this.validateJsonPath(index); - this.checkForSchemaEnhancements(this.numberIndicatorPaths.at(index).get('url').value); } if (this.indicator.defaultId === null) { this.subscriptions.push(this.numberIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => { this.numberIndicatorPaths.at(index).get('result').setValue(null); if (this.numberIndicatorPaths.at(index).get('url').valid) { let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(value), value, this.stakeholder, this.numberIndicatorPaths.at(index).get('jsonPath').value, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(value))); - this.checkForSchemaEnhancements(this.numberIndicatorPaths.at(index).get('url').value); if (this.indicator.indicatorPaths[index]) { this.indicator.indicatorPaths[index] = indicatorPath; } else { @@ -559,11 +560,9 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple if (disableUrl) { this.chartIndicatorPaths.at(index).get('url').disable(); } else { - this.checkForSchemaEnhancements(this.chartIndicatorPaths.at(index).get('url').value); this.urlSubscriptions.push(this.chartIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => { if (this.chartIndicatorPaths.at(index).get('url').valid) { let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(value), value, this.chartIndicatorPaths.at(index).get('type').value, this.stakeholder); - this.checkForSchemaEnhancements(this.chartIndicatorPaths.at(index).get('url').value); (this.chartIndicatorPaths.at(index) as UntypedFormGroup).get('type').setValue(indicatorPath.type); (this.chartIndicatorPaths.at(index) as UntypedFormGroup).setControl('parameters', this.getParametersAsFormArray(indicatorPath)); if (!this.indicator.indicatorPaths[index]) { @@ -889,7 +888,23 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.loading = false; } - reorderIndicators(sectionId: string, type: IndicatorType, reorder: Reorder) { + moveIndicator(moveIndicator: MoveIndicator) { + this.editing = true; + 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.subcategoryIndex]._id + ]; + this.subscriptions.push(this.stakeholderService.moveIndicator(this.properties.monitorServiceAPIURL, path, moveIndicator).subscribe(subCategory => { + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex] = subCategory; + this.setCharts(); + this.setNumbers(); + this.editing = false; + })); + } + + reorderIndicators(sectionId: string, type: IndicatorType, indicators: string[]) { this.editing = true; let path = [ this.stakeholder._id, @@ -898,7 +913,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id, sectionId ]; - this.subscriptions.push(this.stakeholderService.reorderIndicators(this.properties.monitorServiceAPIURL, path, reorder, type).subscribe(indicators => { + this.subscriptions.push(this.stakeholderService.reorderIndicators(this.properties.monitorServiceAPIURL, path, indicators).subscribe(indicators => { if (type === 'chart') { this.charts.find(section => section._id === sectionId).indicators = indicators; this.setCharts(); @@ -1191,10 +1206,6 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple })); } - private checkForSchemaEnhancements(url: string) { - this.showCheckForSchemaEnhancements = this.isAdministrator && url && !this.properties.useOldStatisticsSchema && this.indicatorUtils.checkForSchemaEnhancements(url) && this.properties.dashboard != 'irish'; - } - migrateFromOldImportJsonFile(charts) { // first section contains numbers // second contains charts diff --git a/monitor/services/stakeholder.service.ts b/monitor/services/stakeholder.service.ts index 3f0f3a11..d8b8bf30 100644 --- a/monitor/services/stakeholder.service.ts +++ b/monitor/services/stakeholder.service.ts @@ -1,16 +1,21 @@ import {Injectable} from "@angular/core"; import {HttpClient} from "@angular/common/http"; import {BehaviorSubject, from, Observable, Subscriber} from "rxjs"; -import {Indicator, Section, Stakeholder, StakeholderInfo, Visibility} from "../entities/stakeholder"; +import {Indicator, Section, Stakeholder, StakeholderInfo, SubCategory, Visibility} from "../entities/stakeholder"; import {HelperFunctions} from "../../utils/HelperFunctions.class"; import {map} from "rxjs/operators"; import {properties} from "../../../../environments/environment"; import {CustomOptions} from "../../services/servicesUtils/customOptions.class"; -export interface Reorder { - action: 'moved' | 'added' | 'removed', - target: string, - ids: string[]; +export interface SectionInfo { + id: string; + indicators: string[]; +} + +export interface MoveIndicator { + target: string; + from: SectionInfo; + to: SectionInfo; } @Injectable({ @@ -128,7 +133,6 @@ export class StakeholderService { if (element.alias && element.alias.startsWith('/')) { element.alias = element.alias.slice(1); } - path = HelperFunctions.encodeArray(path); return this.http.post(url + ((path.length > 0) ? '/' : '') + path.join('/') + '/save', element, CustomOptions.registryOptions()).pipe(map(element => { if (path.length === 0) { @@ -140,7 +144,6 @@ export class StakeholderService { } saveBulkElements(url: string, indicators, path: string[] = []): Observable { - path = HelperFunctions.encodeArray(path); return this.http.post(url + ((path.length > 0) ? '/' : '') + path.join('/') + '/save-bulk', indicators, CustomOptions.registryOptions()).pipe(map(element => { if (path.length === 0) { @@ -152,7 +155,6 @@ export class StakeholderService { } saveSection(url: string, element: any, path: string[] = [], index: number = -1): Observable
{ - path = HelperFunctions.encodeArray(path); return this.http.post
(url + ((path.length > 0) ? '/' : '') + path.join('/') + '/save/' + index, element, CustomOptions.registryOptions()).pipe(map(element => { return HelperFunctions.copy(element); @@ -160,7 +162,6 @@ export class StakeholderService { } deleteElement(url: string, path: string[], childrenAction: string = null): Observable { - path = HelperFunctions.encodeArray(path); let params: string = ""; if (childrenAction) { params = "?children=" + childrenAction; @@ -169,17 +170,21 @@ export class StakeholderService { } reorderElements(url: string, path: string[], ids: string[]): Observable { - path = HelperFunctions.encodeArray(path); return this.http.post(url + '/' + path.join('/') + '/reorder', ids, CustomOptions.registryOptions()); } - reorderIndicators(url: string, path: string[], reorder: Reorder, type: string = 'chart'): Observable { - path = HelperFunctions.encodeArray(path); - return this.http.post(url + '/' + path.join('/') + '/' + type + '/reorder', reorder, CustomOptions.registryOptions()).pipe(map(indicators => { + reorderIndicators(url: string, path: string[], indicators: string[]): Observable { + return this.http.post(url + '/' + path.join('/') + '/reorder', indicators, CustomOptions.registryOptions()).pipe(map(indicators => { return HelperFunctions.copy(indicators); })); } + moveIndicator(url: string, path: string[], moveIndicator: MoveIndicator): Observable { + return this.http.post(url + '/' + path.join('/') + '/moveIndicator', moveIndicator, CustomOptions.registryOptions()).pipe(map(subCategory => { + return HelperFunctions.copy(subCategory); + })); + } + getStakeholderAsObservable(): Observable { return this.stakeholderSubject.asObservable(); } From dc1679c56534a505836bc505c75adc3c7ac77fda Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Fri, 5 Apr 2024 11:09:16 +0300 Subject: [PATCH 19/27] [develop | DONE | CHANGED]: newSearchPage.component.html: Restored number of results and keyword display & added uk-text-capitalize on selected filter labels. --- .../searchUtils/newSearchPage.component.html | 75 ++++++++++++------- 1 file changed, 49 insertions(+), 26 deletions(-) diff --git a/searchPages/searchUtils/newSearchPage.component.html b/searchPages/searchUtils/newSearchPage.component.html index ab005f85..d59cb0b1 100644 --- a/searchPages/searchUtils/newSearchPage.component.html +++ b/searchPages/searchUtils/newSearchPage.component.html @@ -1,11 +1,11 @@

-
+
  • - + {{customFilter.valueName}}
  • @@ -15,7 +15,7 @@
  • - + {{type.name}}
- + +
+ +
+ + {{searchUtils.totalResults|number}} + {{type}} + + for + {{searchTerm}} + + + ({{advancedSearchTerms}} rule{{advancedSearchTerms == 1 ? '' : 's'}} applied) + + + + {{oldTotalResults|number}} + {{type}}, page + {{searchUtils.page | number}} + of {{(totalPages(oldTotalResults)|number)}} + +
-
+
+ *ngIf="( entityType !='community' && entityType != 'stakeholder') && usedBy == 'search'" + [isDisabled]="disabled" + [type]="csvPath" [csvParams]="csvParams" [totalResults]="searchUtils.totalResults"> - Data dump + Zenodo dumpData dump
- -
- -
- -
-
+ +
+ class="uk-grid uk-flex-middle uk-child-width-1-1 uk-child-width-1-2@m" uk-grid>
+ class="uk-margin-small-left uk-flex uk-flex-middle" [class.uk-flex-center]="mobile" [class.uk-margin-medium-top]="mobile"> + *ngIf="( entityType !='community' && entityType != 'stakeholder') && usedBy == 'search'" + [isDisabled]="disabled" + [type]="csvPath" [csvParams]="csvParams" [totalResults]="searchUtils.totalResults"> - Data dump + Zenodo dumpData dump
+ +
+ +
+ +
+

For more results please try a new, more specific query

From b71bdfa559a84623bde09f987edc9054a167e588 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Fri, 5 Apr 2024 20:13:05 +0300 Subject: [PATCH 20/27] [new-reorder]: Add multi charts in admin indicators (works now only for charts in UI). Deprecated transition-group disable/enable method. --- dashboard/menu/menu.component.ts | 2 - monitor-admin/topic/indicators.component.html | 1025 ++++++++++------- monitor-admin/topic/indicators.component.ts | 130 ++- monitor-admin/topic/topic.component.ts | 30 +- monitor-admin/topic/topic.module.ts | 3 +- monitor-admin/utils/indicator-utils.ts | 10 + monitor/entities/stakeholder.ts | 1 + ...or-indicator-stakeholder-base.component.ts | 28 +- .../transition-group.component.ts | 16 +- 9 files changed, 758 insertions(+), 487 deletions(-) diff --git a/dashboard/menu/menu.component.ts b/dashboard/menu/menu.component.ts index d756a77f..9f89224b 100644 --- a/dashboard/menu/menu.component.ts +++ b/dashboard/menu/menu.component.ts @@ -372,10 +372,8 @@ export class MenuComponent implements OnInit { } public valueChange() { - this.elements.disable(); this.cdr.detectChanges(); this.elements.init(); - this.elements.enable(); } public get displayMenuItems() { diff --git a/monitor-admin/topic/indicators.component.html b/monitor-admin/topic/indicators.component.html index 1f68e246..2b0a57c3 100644 --- a/monitor-admin/topic/indicators.component.html +++ b/monitor-admin/topic/indicators.component.html @@ -1,456 +1,657 @@
-
-
Number Indicators
-
-
-
-
- -
-
-
-
-
- -
-
-
- - - - -
- +
+ +
+ -
-
{{indicator.name}}
-
- - -- -
-
- -
- +
+ +
-
-
- -
-
-
-
Chart Indicators
-
-
-
-
- -
-
-
-
-
- -
-
-
- - - - -
- +
+
-
-
-
- {{indicator.name}} +
+
+
+
+
+ Create a custom indicator +
+
+ Use our advance tool to create a custom Indicator that suit the needs of your + funding + KPI's. +
+
+ +
+
+
+
- -
- -
-
- -
-
-
-
-
-
-
-
-
-
- Create a custom indicator -
-
- Use our advance tool to create a custom Indicator that suit the needs of your funding - KPI's. -
-
- -
-
-
-
+
+ +
-
-
- -
-
+ [large]="true" classTitle="uk-background-primary uk-light" + (alertOutput)="saveIndicator()" + [okDisabled]="numberIndicatorFb && (numberIndicatorFb.invalid || numberIndicatorFb.pristine)">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{{urlParameterizedMessage}}
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
- JSON Path -
-
-
- This JSON path is not valid or the result has not been calculated yet. - Please press calculate on box below to see the result. -
-
-
-
-
- - - - - - -
-
- -
-
+
-
- +
+
+
+
+
+
+ +
+
+
+
+
+
+
{{ urlParameterizedMessage }}
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ JSON Path +
+
+
+ This JSON path is not valid or the result has not been calculated yet. + Please press calculate on box below to see the result. +
+
+
+
+
+ + + + + + +
+
+ +
+
+
+ +
+
-
-
+
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{{urlParameterizedMessage}}
+ [okDisabled]="chartIndicatorFb && (chartIndicatorFb.invalid || chartIndicatorFb.pristine)"> +
+ +
+
+
+
+
-
- +
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
- +
-
-
- -
-
- + +
+
+ +
+ You are about to delete + "{{ indicator.name ? indicator.name : (indicator.indicatorPaths[0]?.parameters?.title ? indicator.indicatorPaths[0].parameters.title : '') }} + " indicator permanently. +
+ Indicators of all profiles based on this default indicator, will be deleted as well. +
+ Are you sure you want to proceed? +
- You are about to delete - "{{indicator.name ? indicator.name : (indicator.indicatorPaths[0]?.parameters?.title?indicator.indicatorPaths[0].parameters.title:'')}}" indicator permanently. -
- Indicators of all profiles based on this default indicator, will be deleted as well. -
- Are you sure you want to proceed? -
-
- -
-
- + +
+
+ +
+ You are about to delete this section and its indicators permanently. +
+ Sections of all profiles based on this default section and their contents, will be deleted as well. +
+ Are you sure you want to proceed?
- You are about to delete this section and its indicators permanently. -
- Sections of all profiles based on this default section and their contents, will be deleted as well. -
- Are you sure you want to proceed? -
-
-
- +
+
+ +
-
diff --git a/monitor-admin/topic/indicators.component.ts b/monitor-admin/topic/indicators.component.ts index 62883ae6..42e85ddc 100644 --- a/monitor-admin/topic/indicators.component.ts +++ b/monitor-admin/topic/indicators.component.ts @@ -20,7 +20,7 @@ import { Visibility } from "../../monitor/entities/stakeholder"; import { - AbstractControl, + AbstractControl, FormArray, FormGroup, UntypedFormArray, UntypedFormBuilder, UntypedFormControl, @@ -45,6 +45,7 @@ import {NotificationHandler} from "../../utils/notification-handler"; import {IndicatorStakeholderBaseComponent} from "../utils/stakeholder-base.component"; import {properties} from "../../../../environments/environment"; import {StatsProfilesService} from "../utils/services/stats-profiles.service"; +import {TransitionGroupComponent} from "../../utils/transition-group/transition-group.component"; declare var UIkit; declare var copy; @@ -101,6 +102,8 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple @ViewChild('editNumberNotify', {static: true}) editNumberNotify: NotifyFormComponent; @ViewChild('editChartNotify', {static: true}) editChartNotify: NotifyFormComponent; @ViewChild('deleteNotify', {static: true}) deleteNotify: NotifyFormComponent; + /* Transition Groups */ + @ViewChild('transitionGroup') transitionGroup: TransitionGroupComponent; public isFullscreen: boolean = false; @@ -266,7 +269,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple setNumbers() { this.numberSections = this.fb.array([]); this.numberResults.clear(); - let urls: Map = new Map(); + let urls: Map = new Map(); this.numbers.forEach((section, i) => { this.numberSections.push(this.fb.group({ _id: this.fb.control(section._id), @@ -278,11 +281,13 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple indicators: this.fb.control(section.indicators) })); section.indicators.forEach((number, j) => { - let url = this.indicatorUtils.getFullUrl(this.stakeholder, number.indicatorPaths[0]); - const pair = JSON.stringify([number.indicatorPaths[0].source, url]); - const indexes = urls.get(pair) ? urls.get(pair) : []; - indexes.push([i, j]); - urls.set(pair, indexes); + number.indicatorPaths.forEach((indicatorPath, k) => { + let url = this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath); + const pair = JSON.stringify([indicatorPath.source, url]); + const indexes = urls.get(pair) ? urls.get(pair) : []; + indexes.push([i, j, k]); + urls.set(pair, indexes); + }); }); }); this.numberSubscription.forEach(value => { @@ -304,10 +309,10 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple }); } - private calculateResults(response: any, indexes: [number, number][]) { - indexes.forEach(([i, j]) => { + private calculateResults(response: any, indexes: [number, number, number][]) { + indexes.forEach(([i, j, k]) => { let result = JSON.parse(JSON.stringify(response)); - this.numbers[i].indicators[j].indicatorPaths[0].jsonPath.forEach(jsonPath => { + this.numbers[i].indicators[j].indicatorPaths[k].jsonPath.forEach(jsonPath => { if (result) { result = result[jsonPath]; } @@ -320,7 +325,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } else { result = 0; } - this.numberResults.set(i + '-' + j, result); + this.numberResults.set(i + '-' + j + '-' + k, result); }); } @@ -367,6 +372,14 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple return this.chartIndicatorFb.get('indicatorPaths') as UntypedFormArray; } + public getActiveIndicatorPath(indicator: Indicator) { + if(indicator.activePath) { + return indicator.indicatorPaths[indicator.activePath]; + } else { + return indicator.indicatorPaths[0]; + } + } + public getNumberClassBySize(size: IndicatorSize) { if (size === 'small') { return 'uk-width-medium@m uk-width-1-1'; @@ -579,6 +592,65 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } } + public removeNumberIndicatorPath(index: number) { + this.numberIndicatorPaths.removeAt(index); + this.indicator.indicatorPaths.splice(index, 1); + this.transitionGroup.init(); + if(this.indicator.activePath === index) { + this.activeNumberIndicatorPath(Math.max(0, index - 1)); + } else if(this.indicator.activePath > index) { + this.activeNumberIndicatorPath(this.indicator.activePath - 1); + } + this.numberIndicatorFb.markAsDirty(); + } + + public removeChartIndicatorPath(index: number) { + this.chartIndicatorPaths.removeAt(index); + this.indicator.indicatorPaths.splice(index, 1); + this.transitionGroup.init(); + if(this.indicator.activePath === index) { + this.activeChartIndicatorPath(Math.max(0, index - 1)); + } else if(this.indicator.activePath > index) { + this.activeChartIndicatorPath(this.indicator.activePath - 1); + } + this.chartIndicatorFb.markAsDirty(); + } + + public moveIndicatorPath(form: FormGroup, + indicatorPaths: FormArray, index: number, + newIndex: number = index - 1) { + this.transitionGroup.init(); + let a = indicatorPaths.at(index); + let b = indicatorPaths.at(newIndex); + indicatorPaths.setControl(index , b); + indicatorPaths.setControl(newIndex , a); + HelperFunctions.swap(this.indicator.indicatorPaths, index , newIndex); + if(this.indicator.activePath === index) { + this.indicator.activePath = newIndex; + } else if(this.indicator.activePath === newIndex) { + this.indicator.activePath = index; + } + form.markAsDirty(); + } + + public activeNumberIndicatorPath(index: number) { + let paths = this.numberIndicatorPaths; + if(index == paths.length) { + this.addNumberIndicatorPath(); + this.transitionGroup.init(); + } + this.indicator.activePath = index; + } + + public activeChartIndicatorPath(index: number) { + let paths = this.chartIndicatorPaths; + if(index == paths.length) { + this.addChartIndicatorPath(); + this.transitionGroup.init(); + } + this.indicator.activePath = index; + } + private getJsonPathAsFormArray(indicatorPath: IndicatorPath): UntypedFormArray { let jsonPath = this.fb.array([]); if (indicatorPath.jsonPath) { @@ -1273,25 +1345,29 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple if (chart.type == "chart") { indicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(chart.url), chart.url, chart.type, stakeholder); - for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].charts) { - for (let chart of section.indicators) { - if (JSON.stringify(chart.indicatorPaths[0].chartObject) == JSON.stringify(indicatorPath.chartObject)) { - duplicates++; - exists = true; - } - } - } + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].charts.forEach((section: Section) => { + section.indicators.forEach(indicator => { + indicator.indicatorPaths.forEach(path => { + if (JSON.stringify(path.chartObject) == JSON.stringify(indicatorPath.chartObject)) { + duplicates++; + exists = true; + } + }); + }); + }); } else if (chart.type == "number") { indicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(chart.url), chart.url, stakeholder, chart.jsonPath, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(chart.url))); - for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].numbers) { - for (let chart of section.indicators) { - if (JSON.stringify(chart.indicatorPaths[0].chartObject) == JSON.stringify(indicatorPath.chartObject)) { - duplicates++; - exists = true; - } - } - } + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].numbers.forEach((section: Section) => { + section.indicators.forEach(indicator => { + indicator.indicatorPaths.forEach(path => { + if (JSON.stringify(path.chartObject) == JSON.stringify(indicatorPath.chartObject)) { + duplicates++; + exists = true; + } + }); + }); + }); } if (!exists) { let i: Indicator = new Indicator(chart.name, chart.description, chart.additionalDescription, chart.type, chart.width, chart.height, this.showVisibility?"RESTRICTED":this.stakeholderUtils.defaultValue(this.stakeholderUtils.visibilities), [indicatorPath]); diff --git a/monitor-admin/topic/topic.component.ts b/monitor-admin/topic/topic.component.ts index b178eb46..40d128d8 100644 --- a/monitor-admin/topic/topic.component.ts +++ b/monitor-admin/topic/topic.component.ts @@ -242,30 +242,18 @@ export class TopicComponent extends StakeholderBaseComponent implements OnInit, } 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(); } } @@ -359,6 +347,8 @@ export class TopicComponent extends StakeholderBaseComponent implements OnInit, this.stakeholder.topics.splice(this.index, 1); if(this.topicIndex === this.index) { this.chooseTopic(Math.max(0, this.index - 1)); + } else if(this.topicIndex > this.index) { + this.chooseTopic(this.topicIndex - 1); } }, true); }; @@ -388,23 +378,15 @@ export class TopicComponent extends StakeholderBaseComponent implements OnInit, } 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(); } } @@ -500,6 +482,8 @@ export class TopicComponent extends StakeholderBaseComponent implements OnInit, this.stakeholder.topics[this.topicIndex].categories.splice(this.index, 1); if(this.categoryIndex === this.index) { this.chooseCategory(Math.max(0, this.index - 1)); + } else if(this.categoryIndex > this.index) { + this.chooseCategory(this.categoryIndex - 1); } }, true); }; @@ -528,16 +512,12 @@ export class TopicComponent extends StakeholderBaseComponent implements OnInit, } 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(); } } @@ -640,6 +620,8 @@ export class TopicComponent extends StakeholderBaseComponent implements OnInit, 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)); + } else if(this.subCategoryIndex > this.index) { + this.chooseSubcategory(this.subCategoryIndex - 1); } }, true); }; diff --git a/monitor-admin/topic/topic.module.ts b/monitor-admin/topic/topic.module.ts index 71e9b9d9..4c887228 100644 --- a/monitor-admin/topic/topic.module.ts +++ b/monitor-admin/topic/topic.module.ts @@ -20,11 +20,12 @@ import {TransitionGroupModule} from "../../utils/transition-group/transition-gro import {NumberRoundModule} from "../../utils/pipes/number-round.module"; import {SideBarModule} from "../../dashboard/sharedComponents/sidebar/sideBar.module"; import {SidebarMobileToggleModule} from "../../dashboard/sharedComponents/sidebar/sidebar-mobile-toggle/sidebar-mobile-toggle.module"; +import {SliderTabsModule} from "../../sharedComponents/tabs/slider-tabs.module"; @NgModule({ imports: [ CommonModule, TopicRoutingModule, ClickModule, RouterModule, FormsModule, AlertModalModule, - ReactiveFormsModule, InputModule, IconsModule, PageContentModule, LoadingModule, NotifyFormModule, LogoUrlPipeModule, TransitionGroupModule, NumberRoundModule, SideBarModule, SidebarMobileToggleModule + ReactiveFormsModule, InputModule, IconsModule, PageContentModule, LoadingModule, NotifyFormModule, LogoUrlPipeModule, TransitionGroupModule, NumberRoundModule, SideBarModule, SidebarMobileToggleModule, SliderTabsModule ], declarations: [ TopicComponent, IndicatorsComponent diff --git a/monitor-admin/utils/indicator-utils.ts b/monitor-admin/utils/indicator-utils.ts index 9360c228..832b4894 100644 --- a/monitor-admin/utils/indicator-utils.ts +++ b/monitor-admin/utils/indicator-utils.ts @@ -55,6 +55,8 @@ export class StakeholderConfiguration { {icon: 'incognito', value: "PRIVATE", label: 'Private'}, ]; public static CACHE_INDICATORS: boolean = true; + public static NUMBER_MULTI_INDICATOR_PATHS = false; + public static CHART_MULTI_INDICATOR_PATHS = true; } export class StakeholderUtils { @@ -82,6 +84,14 @@ export class StakeholderUtils { return StakeholderConfiguration.CACHE_INDICATORS; } + get hasMultiNumberIndicatorPaths() { + return StakeholderConfiguration.NUMBER_MULTI_INDICATOR_PATHS; + } + + get hasMultiChartIndicatorPaths() { + return StakeholderConfiguration.CHART_MULTI_INDICATOR_PATHS; + } + visibilityIcon: Map = new Map(this.visibilities.map(option => [option.value, option.icon])); defaultValue(options: Option[]) { diff --git a/monitor/entities/stakeholder.ts b/monitor/entities/stakeholder.ts index 49c8e755..a33506ac 100644 --- a/monitor/entities/stakeholder.ts +++ b/monitor/entities/stakeholder.ts @@ -183,6 +183,7 @@ export class Indicator { visibility: Visibility; defaultId: string; indicatorPaths: IndicatorPath[]; + activePath: number = 0; overlay: Overlay = false; constructor(name: string, description: string, additionalDescription:string, type: IndicatorType, width: IndicatorSize,height: IndicatorSize, visibility: Visibility, indicatorPaths: IndicatorPath[], defaultId: string = null) { diff --git a/monitor/monitor-indicator-stakeholder-base.component.ts b/monitor/monitor-indicator-stakeholder-base.component.ts index 4573dee4..8838d202 100644 --- a/monitor/monitor-indicator-stakeholder-base.component.ts +++ b/monitor/monitor-indicator-stakeholder-base.component.ts @@ -214,15 +214,17 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator (this.periodFilter.selectedFromValue && this.periodFilter.selectedToValue ? " - " : "") + (this.periodFilter.selectedToValue ? this.periodFilter.selectedToValue : "")) : ""); //clear numbers when filters change this.numberResults.clear(); - let urls: Map = new Map(); + let urls: Map = new Map(); this.activeSubCategory.numbers.forEach((section, i) => { section.indicators.forEach((number, j) => { if (this.hasPermission(number.visibility)) { - let url = this.getFullUrl(number.indicatorPaths[0]); - const pair = JSON.stringify([number.indicatorPaths[0].source, url]); - const indexes = urls.get(pair) ? urls.get(pair) : []; - indexes.push([i, j]); - urls.set(pair, indexes); + number.indicatorPaths.forEach((indicatorPath, k) => { + let url = this.getFullUrl(indicatorPath); + const pair = JSON.stringify([indicatorPath.source, url]); + const indexes = urls.get(pair) ? urls.get(pair) : []; + indexes.push([i, j, k]); + urls.set(pair, indexes); + }) } }); }); @@ -231,10 +233,10 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator let activeSubcategory = this.activeSubCategory._id; this.subscriptions.push(this.statisticsService.getNumbers(this.indicatorUtils.getSourceType(pair[0]), pair[1]).subscribe(response => { if(activeSubcategory === this.activeSubCategory._id) { - indexes.forEach(([i, j]) => { + indexes.forEach(([i, j, k]) => { if( this.activeSubCategory?.numbers[i]?.indicators[j]) { let result = JSON.parse(JSON.stringify(response)); - this.activeSubCategory.numbers[i].indicators[j].indicatorPaths[0].jsonPath.forEach(jsonPath => { + this.activeSubCategory.numbers[i].indicators[j].indicatorPaths[k].jsonPath.forEach(jsonPath => { if (result) { result = result[jsonPath]; } @@ -247,7 +249,7 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator } else { result = 0; } - this.numberResults.set(i + '-' + j, result); + this.numberResults.set(i + '-' + j + '-' + k, result); } }); } @@ -255,10 +257,10 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator }); this.activeSubCategory.charts.forEach((section, i) => { section.indicators.forEach((indicator, j) => { - if (indicator.indicatorPaths.length > 0) { - indicator.indicatorPaths[0].safeResourceUrl = this.getUrlByStakeHolder(indicator.indicatorPaths[0]); - this.chartsActiveType.set(i + '-' + j, indicator.indicatorPaths[0]); - } + indicator.indicatorPaths.forEach((indicatorPath, k) => { + indicator.indicatorPaths[k].safeResourceUrl = this.getUrlByStakeHolder(indicator.indicatorPaths[k]); + this.chartsActiveType.set(i + '-' + j + '-' + k, indicator.indicatorPaths[k]); + }); }); }); if (this.cdr && !(this.cdr as ViewRef).destroyed) { diff --git a/utils/transition-group/transition-group.component.ts b/utils/transition-group/transition-group.component.ts index 53530868..8cea910d 100644 --- a/utils/transition-group/transition-group.component.ts +++ b/utils/transition-group/transition-group.component.ts @@ -1,6 +1,6 @@ import {TransitionGroupItemDirective} from "./transition-group-item.directive"; import { - AfterViewInit, + AfterViewInit, ChangeDetectorRef, Component, ContentChildren, ElementRef, Input, @@ -29,15 +29,14 @@ export class TransitionGroupComponent implements AfterViewInit, OnDestroy { @ContentChildren(TransitionGroupItemDirective) items: QueryList; @Input() public id: string; - private disabled: boolean = false; + public size: number; private subscription: Subscription; constructor(public element: ElementRef) {} ngAfterViewInit() { - this.init(); this.subscription = this.items.changes.subscribe(items => { - if(!this.disabled) { + if(items.length === this.size) { items.forEach(item => item.prevPos = item.newPos || item.prevPos); items.forEach(this.runCallback); this.refreshPosition('newPos'); @@ -80,6 +79,7 @@ export class TransitionGroupComponent implements AfterViewInit, OnDestroy { init() { this.refreshPosition('prevPos'); this.refreshPosition('newPos'); + this.size = this.items.length; } runCallback(item: TransitionGroupItemDirective) { @@ -126,17 +126,17 @@ export class TransitionGroupComponent implements AfterViewInit, OnDestroy { /** * Enable transition - * + * @deprecated * */ enable() { - this.disabled = false; + console.debug('Deprecated') } /** * Disable transition - * + * @deprecated * */ disable() { - this.disabled = true; + console.debug('Deprecated') } } From e91830f2f8c1182c6e728f87a03af3a2932d816e Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Fri, 5 Apr 2024 20:31:29 +0300 Subject: [PATCH 21/27] [develop]: Monitor base component delete chartsActiveType --- .../monitor-indicator-stakeholder-base.component.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/monitor/monitor-indicator-stakeholder-base.component.ts b/monitor/monitor-indicator-stakeholder-base.component.ts index 8838d202..c6d388e3 100644 --- a/monitor/monitor-indicator-stakeholder-base.component.ts +++ b/monitor/monitor-indicator-stakeholder-base.component.ts @@ -53,7 +53,6 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator minYear = Dates.currentYear - 20; maxYear = Dates.currentYear; public numberResults: Map = new Map(); - public chartsActiveType: Map = new Map(); public clipboard; /** Services */ @@ -259,7 +258,6 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator section.indicators.forEach((indicator, j) => { indicator.indicatorPaths.forEach((indicatorPath, k) => { indicator.indicatorPaths[k].safeResourceUrl = this.getUrlByStakeHolder(indicator.indicatorPaths[k]); - this.chartsActiveType.set(i + '-' + j + '-' + k, indicator.indicatorPaths[k]); }); }); }); @@ -273,10 +271,12 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator this.indicatorUtils.getChartUrl(indicatorPath.source, this.getFullUrl(indicatorPath))); } - public setActiveChart(i: number, j: number, type: string) { - let activeChart = this.activeSubCategory.charts[i].indicators[j].indicatorPaths.filter(indicatorPath => indicatorPath.type === type)[0]; - activeChart.safeResourceUrl = this.getUrlByStakeHolder(activeChart); - this.chartsActiveType.set(i + '-' + j, activeChart); + public getActiveIndicatorPath(indicator: Indicator) { + if(indicator.activePath) { + return indicator.indicatorPaths[indicator.activePath]; + } else { + return indicator.indicatorPaths[0]; + } } public filter() { From 4f10c5c5f4a42629ac4eb13f3a1e3977ab353b86 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Sat, 6 Apr 2024 03:10:51 +0300 Subject: [PATCH 22/27] [develop]: Align import/export indicators with multi indicator paths. --- monitor-admin/topic/indicators.component.html | 2 - monitor-admin/topic/indicators.component.ts | 306 +++++++++--------- 2 files changed, 158 insertions(+), 150 deletions(-) diff --git a/monitor-admin/topic/indicators.component.html b/monitor-admin/topic/indicators.component.html index 2b0a57c3..69abb1dd 100644 --- a/monitor-admin/topic/indicators.component.html +++ b/monitor-admin/topic/indicators.component.html @@ -339,7 +339,6 @@
-
{{ urlParameterizedMessage }}
diff --git a/monitor-admin/topic/indicators.component.ts b/monitor-admin/topic/indicators.component.ts index 42e85ddc..9be745ae 100644 --- a/monitor-admin/topic/indicators.component.ts +++ b/monitor-admin/topic/indicators.component.ts @@ -97,7 +97,6 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple public sectionTypeToDelete: string; public sectionChildrenActionOnDelete: string; public indicatorChildrenActionOnDelete: string; - public urlParameterizedMessage = null; private notification: Notification; @ViewChild('editNumberNotify', {static: true}) editNumberNotify: NotifyFormComponent; @ViewChild('editChartNotify', {static: true}) editChartNotify: NotifyFormComponent; @@ -210,11 +209,11 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.reorderIndicators(section._id, 'number', callback(list)); })); this.subscriptions.push(UIkit.util.on(document, 'added', '#number-' + section._id, (list): void => { - this.to.next({id: section._id, indicators: callback(list)}); + this.to.next({id: section._id, indicators: callback(list)}); })); this.subscriptions.push(UIkit.util.on(document, 'removed', '#number-' + section._id, (list): void => { let sub = this.to.asObservable().subscribe(to => { - if(to) { + if (to) { let from: SectionInfo = {id: section._id, indicators: callback(list)}; this.moveIndicator({target: list.detail[1].id, from: from, to: to}); setTimeout(() => { @@ -232,7 +231,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple //callback(list, "chart", 'added'); })); this.subscriptions.push(UIkit.util.on(document, 'removed', '#chart-' + section._id, (list): void => { - // callback(list, "chart", 'removed'); + // callback(list, "chart", 'removed'); })); }); } @@ -331,8 +330,8 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple get charts(): Section[] { if (this.stakeholder.topics[this.topicIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) { + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) { return this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].charts; } else { return []; @@ -341,8 +340,8 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple get numbers(): Section[] { if (this.stakeholder.topics[this.topicIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) { + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) { return this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].numbers; } else { return []; @@ -359,9 +358,9 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple get canEdit() { return this.stakeholder && - this.stakeholder.topics[this.topicIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex] && !this.loading; + this.stakeholder.topics[this.topicIndex] && + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex] && !this.loading; } public get numberIndicatorPaths(): UntypedFormArray { @@ -373,7 +372,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } public getActiveIndicatorPath(indicator: Indicator) { - if(indicator.activePath) { + if (indicator.activePath) { return indicator.indicatorPaths[indicator.activePath]; } else { return indicator.indicatorPaths[0]; @@ -476,7 +475,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } public getParameters(index: number, type: IndicatorType = 'chart'): UntypedFormArray { - if(type === 'chart') { + if (type === 'chart') { return this.chartIndicatorPaths.at(index).get('parameters') as UntypedFormArray; } else { return this.numberIndicatorPaths.at(index).get('parameters') as UntypedFormArray; @@ -489,7 +488,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple private getSecureUrlByStakeHolder(indicatorPath: IndicatorPath) { return this.sanitizer.bypassSecurityTrustResourceUrl( - this.indicatorUtils.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath))); + this.indicatorUtils.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath))); } private getUrlByStakeHolder(indicatorPath: IndicatorPath) { @@ -501,13 +500,13 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple jsonPath.push(this.fb.control('', Validators.required)); } this.numberIndicatorPaths.push(this.fb.group({ - url: this.fb.control(url, [Validators.required, StringUtils.urlValidator()]), - jsonPath: jsonPath, - result: this.fb.control(0, Validators.required), - source: this.fb.control(source, Validators.required), - parameters: parameters, - format: this.fb.control(format, Validators.required) - } + url: this.fb.control(url, [Validators.required, StringUtils.urlValidator()]), + jsonPath: jsonPath, + result: this.fb.control(0, Validators.required), + source: this.fb.control(source, Validators.required), + parameters: parameters, + format: this.fb.control(format, Validators.required) + } )); let index = this.numberIndicatorPaths.length - 1; if (this.numberIndicatorPaths.at(index).get('url').valid) { @@ -515,45 +514,43 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } if (this.indicator.defaultId === null) { this.subscriptions.push(this.numberIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => { - this.numberIndicatorPaths.at(index).get('result').setValue(null); - if (this.numberIndicatorPaths.at(index).get('url').valid) { - let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(value), value, this.stakeholder, this.numberIndicatorPaths.at(index).get('jsonPath').value, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(value))); - if (this.indicator.indicatorPaths[index]) { - this.indicator.indicatorPaths[index] = indicatorPath; - } else { - this.indicator.indicatorPaths.push(indicatorPath); - } - if (indicatorPath.source) { - this.numberIndicatorPaths.at(index).get('source').setValue(indicatorPath.source); - } - (this.numberIndicatorPaths.at(index) as UntypedFormGroup).setControl('parameters', this.getParametersAsFormArray(indicatorPath)); - if (indicatorPath.jsonPath.length > 1 && this.getJsonPath(index).length == 1) { - let paths = indicatorPath.jsonPath; - for (let i = 0; i < paths.length; i++) { - if (i == this.getJsonPath(index).length) { - this.getJsonPath(index).push(this.fb.control('', Validators.required)); - } + this.numberIndicatorPaths.at(index).get('result').setValue(null); + if (this.numberIndicatorPaths.at(index).get('url').valid) { + let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(value), value, this.stakeholder, this.numberIndicatorPaths.at(index).get('jsonPath').value, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(value))); + if (this.indicator.indicatorPaths[index]) { + this.indicator.indicatorPaths[index] = indicatorPath; + } else { + this.indicator.indicatorPaths.push(indicatorPath); + } + if (indicatorPath.source) { + this.numberIndicatorPaths.at(index).get('source').setValue(indicatorPath.source); + } + (this.numberIndicatorPaths.at(index) as UntypedFormGroup).setControl('parameters', this.getParametersAsFormArray(indicatorPath)); + if (indicatorPath.jsonPath.length > 1 && this.getJsonPath(index).length == 1) { + let paths = indicatorPath.jsonPath; + for (let i = 0; i < paths.length; i++) { + if (i == this.getJsonPath(index).length) { + this.getJsonPath(index).push(this.fb.control('', Validators.required)); + } + } + this.getJsonPath(index).setValue(paths) } - this.getJsonPath(index).setValue(paths) } - } else { - this.urlParameterizedMessage = null; - } - }) + }) ); this.subscriptions.push(this.numberIndicatorPaths.at(index).get('jsonPath').valueChanges.subscribe(value => { - if (this.indicator.indicatorPaths[index]) { - this.indicator.indicatorPaths[index].jsonPath = value; - } - this.numberIndicatorPaths.at(index).get('result').setValue(null); - }) + if (this.indicator.indicatorPaths[index]) { + this.indicator.indicatorPaths[index].jsonPath = value; + } + this.numberIndicatorPaths.at(index).get('result').setValue(null); + }) ); this.subscriptions.push(this.numberIndicatorPaths.at(index).get('source').valueChanges.subscribe(value => { - if (this.indicator.indicatorPaths[index]) { - this.indicator.indicatorPaths[index].source = value; - } - }) + if (this.indicator.indicatorPaths[index]) { + this.indicator.indicatorPaths[index].source = value; + } + }) ); } else { this.numberIndicatorPaths.at(index).get('url').disable(); @@ -564,10 +561,10 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple public addChartIndicatorPath(value: string = '', parameters: UntypedFormArray = new UntypedFormArray([]), disableUrl: boolean = false, type: string = null) { this.chartIndicatorPaths.push(this.fb.group({ - url: this.fb.control(value, [Validators.required, StringUtils.urlValidator()]), - parameters: parameters, - type: this.fb.control(type) - } + url: this.fb.control(value, [Validators.required, StringUtils.urlValidator()]), + parameters: parameters, + type: this.fb.control(type) + } )); let index = this.chartIndicatorPaths.length - 1; if (disableUrl) { @@ -585,8 +582,6 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple indicatorPath.safeResourceUrl = this.indicator.indicatorPaths[index].safeResourceUrl; this.indicator.indicatorPaths[index] = indicatorPath; } - } else { - this.urlParameterizedMessage = null; } })); } @@ -596,9 +591,9 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.numberIndicatorPaths.removeAt(index); this.indicator.indicatorPaths.splice(index, 1); this.transitionGroup.init(); - if(this.indicator.activePath === index) { + if (this.indicator.activePath === index) { this.activeNumberIndicatorPath(Math.max(0, index - 1)); - } else if(this.indicator.activePath > index) { + } else if (this.indicator.activePath > index) { this.activeNumberIndicatorPath(this.indicator.activePath - 1); } this.numberIndicatorFb.markAsDirty(); @@ -608,9 +603,9 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.chartIndicatorPaths.removeAt(index); this.indicator.indicatorPaths.splice(index, 1); this.transitionGroup.init(); - if(this.indicator.activePath === index) { + if (this.indicator.activePath === index) { this.activeChartIndicatorPath(Math.max(0, index - 1)); - } else if(this.indicator.activePath > index) { + } else if (this.indicator.activePath > index) { this.activeChartIndicatorPath(this.indicator.activePath - 1); } this.chartIndicatorFb.markAsDirty(); @@ -622,12 +617,12 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.transitionGroup.init(); let a = indicatorPaths.at(index); let b = indicatorPaths.at(newIndex); - indicatorPaths.setControl(index , b); - indicatorPaths.setControl(newIndex , a); - HelperFunctions.swap(this.indicator.indicatorPaths, index , newIndex); - if(this.indicator.activePath === index) { + indicatorPaths.setControl(index, b); + indicatorPaths.setControl(newIndex, a); + HelperFunctions.swap(this.indicator.indicatorPaths, index, newIndex); + if (this.indicator.activePath === index) { this.indicator.activePath = newIndex; - } else if(this.indicator.activePath === newIndex) { + } else if (this.indicator.activePath === newIndex) { this.indicator.activePath = index; } form.markAsDirty(); @@ -635,7 +630,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple public activeNumberIndicatorPath(index: number) { let paths = this.numberIndicatorPaths; - if(index == paths.length) { + if (index == paths.length) { this.addNumberIndicatorPath(); this.transitionGroup.init(); } @@ -644,7 +639,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple public activeChartIndicatorPath(index: number) { let paths = this.chartIndicatorPaths; - if(index == paths.length) { + if (index == paths.length) { this.addChartIndicatorPath(); this.transitionGroup.init(); } @@ -684,7 +679,21 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } public editNumberIndicatorOpen(section: Section, id = null) { - this.urlParameterizedMessage = null; + this.editNumberModal.cancelButtonText = 'Cancel'; + this.editNumberModal.okButtonLeft = false; + this.editNumberModal.alertMessage = false; + if (this.index === -1) { + this.editNumberModal.alertTitle = 'Create a new number indicator'; + this.editNumberModal.okButtonText = 'Save'; + this.notification = NotificationUtils.createIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); + this.editNumberNotify.reset(this.notification.message); + } else { + this.editNumberModal.alertTitle = 'Edit number indicator\'s information'; + this.editNumberModal.okButtonText = 'Save Changes'; + this.notification = NotificationUtils.editIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); + this.editNumberNotify.reset(this.notification.message); + } + this.editNumberModal.stayOpen = true; this.section = section; this.index = (id) ? section.indicators.findIndex(value => value._id === id) : -1; if (this.index !== -1) { @@ -726,26 +735,26 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.numberIndicatorFb.get('description').disable(); }, 0); } - this.editNumberModal.cancelButtonText = 'Cancel'; - this.editNumberModal.okButtonLeft = false; - this.editNumberModal.alertMessage = false; - if (this.index === -1) { - this.editNumberModal.alertTitle = 'Create a new number indicator'; - this.editNumberModal.okButtonText = 'Save'; - this.notification = NotificationUtils.createIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - this.editNumberNotify.reset(this.notification.message); - } else { - this.editNumberModal.alertTitle = 'Edit number indicator\'s information'; - this.editNumberModal.okButtonText = 'Save Changes'; - this.notification = NotificationUtils.editIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - this.editNumberNotify.reset(this.notification.message); - } - this.editNumberModal.stayOpen = true; this.editNumberModal.open(); } public editChartIndicatorOpen(section: Section, id = null) { - this.urlParameterizedMessage = null; + this.editChartModal.cancelButtonText = 'Cancel'; + this.editChartModal.okButtonLeft = false; + this.editChartModal.alertMessage = false; + if (this.index === -1) { + this.editChartModal.alertTitle = 'Create a new chart indicator'; + this.editChartModal.okButtonText = 'Save'; + this.notification = NotificationUtils.createIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); + this.editChartNotify.reset(this.notification.message); + } else { + this.editChartModal.alertTitle = 'Edit chart indicator\'s information'; + this.editChartModal.okButtonText = 'Save Changes'; + this.notification = NotificationUtils.editIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); + ; + this.editChartNotify.reset(this.notification.message); + } + this.editChartModal.stayOpen = true; this.urlSubscriptions.forEach(value => { if (value instanceof Subscriber) { value.unsubscribe(); @@ -769,7 +778,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple }); this.indicator.indicatorPaths.forEach(indicatorPath => { this.addChartIndicatorPath(this.getUrlByStakeHolder(indicatorPath), - this.getParametersAsFormArray(indicatorPath), this.indicator.defaultId !== null, indicatorPath.type); + this.getParametersAsFormArray(indicatorPath), this.indicator.defaultId !== null, indicatorPath.type); indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); }); } else { @@ -792,22 +801,6 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.chartIndicatorFb.get('description').disable(); }, 0); } - this.editChartModal.cancelButtonText = 'Cancel'; - this.editChartModal.okButtonLeft = false; - this.editChartModal.alertMessage = false; - if (this.index === -1) { - this.editChartModal.alertTitle = 'Create a new chart indicator'; - this.editChartModal.okButtonText = 'Save'; - this.notification = NotificationUtils.createIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - this.editChartNotify.reset(this.notification.message); - } else { - this.editChartModal.alertTitle = 'Edit chart indicator\'s information'; - this.editChartModal.okButtonText = 'Save Changes'; - this.notification = NotificationUtils.editIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - ; - this.editChartNotify.reset(this.notification.message); - } - this.editChartModal.stayOpen = true; this.editChartModal.open(); } @@ -907,7 +900,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.setCharts(); this.setNumbers(); this.initReorder(); - if(properties.notificationsAPIURL) { + if (properties.notificationsAPIURL) { this.notification = NotificationUtils.importIndicators(this.user.fullname, this.stakeholder.alias); this.notification.entity = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index]._id; this.notification.name = this.user.firstname; @@ -999,7 +992,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple hasDifference(index: number, type: IndicatorType = 'chart'): boolean { let hasDifference = false; - if(type === 'chart') { + if (type === 'chart') { this.chartIndicatorPaths.at(index).value.parameters.forEach(parameter => { if (parameter.value !== this.indicator.indicatorPaths[index].parameters[parameter.key]) { hasDifference = true; @@ -1008,7 +1001,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple }); return hasDifference || this.indicator.indicatorPaths[index].safeResourceUrl.toString() !== this.getSecureUrlByStakeHolder(this.indicator.indicatorPaths[index]).toString(); - } else if(type === 'number') { + } else if (type === 'number') { let indicatorPath = this.numberIndicatorPaths.at(index).value; indicatorPath.parameters.forEach(parameter => { if (parameter.value !== this.indicator.indicatorPaths[index].parameters[parameter.key]) { @@ -1029,12 +1022,12 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } refreshIndicator(type: IndicatorType = 'chart') { - if(type === 'chart') { + if (type === 'chart') { this.indicator = this.indicatorUtils.generateIndicatorByForm(this.chartIndicatorFb.value, this.indicator.indicatorPaths, 'chart'); this.indicator.indicatorPaths.forEach(indicatorPath => { indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); }); - } else if(type === 'number') { + } else if (type === 'number') { this.indicator = this.indicatorUtils.generateIndicatorByForm(this.numberIndicatorFb.value, this.indicator.indicatorPaths, 'number'); this.indicator.indicatorPaths.forEach((indicatorPath, index) => { this.validateJsonPath(index); @@ -1293,6 +1286,11 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple if (chart['sectionIndex'] == null) { chart['sectionIndex'] = chart['type'] == 'chart' ? chartsSection : 0; } + if (chart.url && chart.jsonPath) { + chart.indicatorPaths = [{url: chart.url, jsonPath: chart.jsonPath}]; + } else if(chart.url) { + chart.indicatorPaths = [{url: chart.url}]; + } } return charts; } @@ -1300,7 +1298,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple importIndicatorsAndSave(stakeholder: Stakeholder, charts: any[]) { let sectionsToSave: Section[] = []; let countIndicators = 0; - if(stakeholder.type !== this.stakeholder.type) { + if (stakeholder.type !== this.stakeholder.type) { UIkit.notification("The type of this profile is not the same with the file's one!", { status: 'warning', timeout: 6000, @@ -1313,23 +1311,25 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple let duplicates = 0; charts = this.migrateFromOldImportJsonFile(charts); for (let chart of charts) { - chart.visibility = this.showVisibility?chart.visibility:this.stakeholderUtils.defaultValue(this.stakeholderUtils.visibilities); + chart.visibility = this.showVisibility ? chart.visibility : this.stakeholderUtils.defaultValue(this.stakeholderUtils.visibilities); if (!sectionsToSave[chart['sectionIndex']]) { let sectionToSave = new Section(chart['sectionType'] ? chart['sectionType'] : chart['type'], chart['sectionTitle']); sectionToSave.indicators = []; sectionsToSave[chart['sectionIndex']] = sectionToSave; } let exists = false; - let indicatorPath; + let indicatorPaths: IndicatorPath[] = []; // validate indicators' schema from file let invalid_file_message; if (!chart.type) { invalid_file_message = "No indicator type is specified. Type should be chart or number."; } else if (chart.type != "chart" && chart.type != "number") { invalid_file_message = "Invalid indicator type. Type should be chart or number."; - } else if (chart.type == "number" && !chart.jsonPath) { + } else if (chart.indicatorPaths.length === 0) { + invalid_file_message = "No indicator paths are specified." + } else if (chart.type == "number" && chart.indicatorPaths.filter(path => !path.jsonPath).length > 0) { invalid_file_message = "No jsonPath is specified for number indicator." - } else if (!chart.url) { + } else if (chart.indicatorPaths.filter(path => !path.url).length > 0) { invalid_file_message = "No indicator url is specified."; } @@ -1344,33 +1344,38 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } if (chart.type == "chart") { - indicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(chart.url), chart.url, chart.type, stakeholder); + indicatorPaths = chart.indicatorPaths.map(path => this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(path.url), path.url, chart.type, stakeholder)); this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].charts.forEach((section: Section) => { section.indicators.forEach(indicator => { indicator.indicatorPaths.forEach(path => { - if (JSON.stringify(path.chartObject) == JSON.stringify(indicatorPath.chartObject)) { - duplicates++; + let size = indicatorPaths.length; + indicatorPaths = indicatorPaths.filter(indicatorPath => JSON.stringify(path.chartObject) !== JSON.stringify(indicatorPath.chartObject)) + if (indicatorPaths.length < size) { + duplicates = duplicates + (size - indicatorPaths.length); exists = true; } }); }); }); } else if (chart.type == "number") { - indicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(chart.url), chart.url, stakeholder, - chart.jsonPath, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(chart.url))); + indicatorPaths = chart.indicatorPaths.map(path => + this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(path.url), path.url, + stakeholder, path.jsonPath, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(path.url)))); this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].numbers.forEach((section: Section) => { section.indicators.forEach(indicator => { indicator.indicatorPaths.forEach(path => { - if (JSON.stringify(path.chartObject) == JSON.stringify(indicatorPath.chartObject)) { - duplicates++; + let size = indicatorPaths.length; + indicatorPaths = indicatorPaths.filter(indicatorPath => JSON.stringify(path.chartObject) !== JSON.stringify(indicatorPath.chartObject)) + if (indicatorPaths.length < size) { + duplicates = duplicates + (size - indicatorPaths.length); exists = true; } }); }); }); } - if (!exists) { - let i: Indicator = new Indicator(chart.name, chart.description, chart.additionalDescription, chart.type, chart.width, chart.height, this.showVisibility?"RESTRICTED":this.stakeholderUtils.defaultValue(this.stakeholderUtils.visibilities), [indicatorPath]); + if (indicatorPaths.length > 0) { + let i: Indicator = new Indicator(chart.name, chart.description, chart.additionalDescription, chart.type, chart.width, chart.height, this.showVisibility ? "RESTRICTED" : this.stakeholderUtils.defaultValue(this.stakeholderUtils.visibilities), indicatorPaths); sectionsToSave[chart['sectionIndex']].indicators.push(i); countIndicators++; } @@ -1402,36 +1407,41 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple let indexIndicator: number = 0; this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[subcategoryIndex].numbers.forEach(section => { section.indicators.forEach(indicator => { - indicator.indicatorPaths.forEach(indicatorPath => { - indicators[indexIndicator] = { - "type": indicator.type, "name": indicator.name, "jsonPath": indicatorPath.jsonPath, - "description": indicator.description, "additionalDescription": indicator.additionalDescription, - "visibility": indicator.visibility, "width": indicator.width, "height": indicator.height, - "url": this.indicatorUtils.getNumberUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)), - "sectionTitle": section.title, - "sectionType": section.type, - "sectionIndex": index - }; - indexIndicator++; - }); + indicators[indexIndicator] = { + "indicatorPaths": indicator.indicatorPaths.map(path => { + return { + jsonPath: path.jsonPath, + url: this.indicatorUtils.getNumberUrl(path.source, this.indicatorUtils.getFullUrl(this.stakeholder, path)) + } + }), + "type": indicator.type, "name": indicator.name, + "description": indicator.description, "additionalDescription": indicator.additionalDescription, + "visibility": indicator.visibility, "width": indicator.width, "height": indicator.height, + "sectionTitle": section.title, + "sectionType": section.type, + "sectionIndex": index + }; + indexIndicator++; }); index++; }); this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[subcategoryIndex].charts.forEach(section => { section.indicators.forEach(indicator => { - indicator.indicatorPaths.forEach(indicatorPath => { - indicators[indexIndicator] = { - "type": indicator.type, "name": indicator.name, - "description": indicator.description, "additionalDescription": indicator.additionalDescription, - "visibility": indicator.visibility, "width": indicator.width, "height": indicator.height, - "url": this.getUrlByStakeHolder(indicatorPath), - "sectionTitle": section.title, - "sectionType": section.type, - "sectionIndex": index - }; - indexIndicator++; - }); + indicators[indexIndicator] = { + "indicatorPaths": indicator.indicatorPaths.map(path => { + return { + url: this.getUrlByStakeHolder(path) + } + }), + "type": indicator.type, "name": indicator.name, + "description": indicator.description, "additionalDescription": indicator.additionalDescription, + "visibility": indicator.visibility, "width": indicator.width, "height": indicator.height, + "sectionTitle": section.title, + "sectionType": section.type, + "sectionIndex": index + }; + indexIndicator++; }); index++; @@ -1491,7 +1501,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.makeFileRequest(this.properties.utilsService + '/upload?type=json', [], this.filesToUpload).then(async (result: string) => { let json = JSON.parse(result); // validate file - if(json && Array.isArray(json)) { + if (json && Array.isArray(json)) { UIkit.notification("This file is not supported any more. Please export indicators and try again!", { status: 'danger', timeout: 6000, From 69cdb2cec2001ece062af3b2b629d2ce9cdf4867 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Mon, 8 Apr 2024 14:14:09 +0300 Subject: [PATCH 23/27] [develop]: Add roles in stakeholder configuration to handle naming of roles in different services. --- .../role-users/role-users.component.html | 22 +++++++++---------- .../users/role-users/role-users.component.ts | 17 +++++++++----- monitor-admin/utils/indicator-utils.ts | 10 +++++++++ .../role-verification.component.ts | 6 +++-- utils/email/composer.ts | 7 +++--- 5 files changed, 41 insertions(+), 21 deletions(-) diff --git a/dashboard/users/role-users/role-users.component.html b/dashboard/users/role-users/role-users.component.html index 6fb1d94f..88befe57 100644 --- a/dashboard/users/role-users/role-users.component.html +++ b/dashboard/users/role-users/role-users.component.html @@ -8,26 +8,26 @@
+ [searchControl]="filterForm.get('active')" [expandable]="true" [placeholder]="'Search ' + stakeholderUtils.roles[role] + 's'" searchInputClass="outer">
-